JavaRush /Java блогу /Random-KY /Дизайн үлгү адаптери

Дизайн үлгү адаптери

Группада жарыяланган
Салам! Бүгүн биз маанилүү жаңы темага токтолобуз - үлгүлөр, же башкача айтканда - дизайн үлгүлөрү . Үлгүлөр деген эмне? Менимче, сиз "дөңгөлөктү кайра ойлоп таппаңыз" деген сөздү билесиз. Программалоодо, башка көптөгөн тармактардагыдай эле, типтүү кырдаалдардын көп саны бар. Алардын ар бири үчүн программалоону иштеп чыгуу процессинде даяр жумушчу чечимдер түзүлгөн. Бул дизайн үлгүлөрү. Салыштырмалуу айтканда, үлгү - бул кырдаалга чечим сунуш кылган белгилүү бир мисал: "эгерде сиздин программаңыз бир нерсе кылышы керек болсо, аны кантип жасоо керек". Үлгүлөр көп, аларга эң сонун китеп "Дизайн үлгүлөрүн изилдөө" арналган, аны сөзсүз окушуңуз керек. Дизайн үлгүсү "Адаптер" - 2Мүмкүн болушунча кыскача айтканда, үлгү стандарттын бир түрү катары каралышы мүмкүн болгон жалпы көйгөйдөн жана аны чечүүдөн турат. Бүгүнкү лекцияда биз «Адаптер» деп аталган бул калыптардын бири менен таанышабыз. Анын аты айтып турат, жана сиз чыныгы жашоодо адаптерлерди бир эмес, бир нече жолу кезиктирдиңиз. Кеңири таралган адаптерлердин бири - көптөгөн компьютерлер жана ноутбуктар менен жабдылган карта окугучтары. Дизайн үлгүсү "Адаптер" - 3Элестеткиле, бизде кандайдыр бир эстутум картасы бар. Эмне маселе? Чындыгында ал компьютер менен кантип иштешүүнү билбейт. Алардын жалпы интерфейси жок. Компьютерде USB туташтыргычы бар, бирок ага эстутум картасын кыстара албайсыз. Картаны компьютерге киргизүү мүмкүн эмес, андыктан фото, видео жана башка маалыматтарыбызды сактай албайбыз. Картаны окугуч бул маселени чечүүчү адаптер. Анткени, анын USB кабели бар! Картанын өзүнөн айырмаланып, картаны окугучту компьютерге киргизүүгө болот. Алардын компьютер менен жалпы интерфейси бар - USB. Мисал менен анын кандай болорун карап көрөлү:
public interface USB {

   void connectWithUsbCable();
}
Бул биздин USB интерфейсибиз жана USB кабелин киргизүүнүн жалгыз ыкмасы:
public class MemoryCard {

   public void insert() {
       System.out.println("Карта памяти успешно вставлена!");
   }

   public void copyData() {
       System.out.println("Данные скопированы на компьютер!");
   }
}
Бул эстутум картасын ишке ашырган биздин класс. Буга чейин бизге керек болгон 2 ыкма бар, бирок бул жерде көйгөй: ал USB интерфейсин ишке ашырbyte. Картаны USB уячасына салуу мүмкүн эмес.
public class CardReader implements USB {

   private MemoryCard memoryCard;

   public CardReader(MemoryCard memoryCard) {
       this.memoryCard = memoryCard;
   }

   @Override
   public void connectWithUsbCable() {
       this.memoryCard.insert();
       this.memoryCard.copyData();
   }
}
Жана бул жерде биздин адаптер! КлассCardReader эмне кылат жана эмне үчүн ал адаптер? Баары оңой. Ыңгайлаштырылган класс (эс тутум картасы) адаптердин талааларынын бирине айланат. Бул логикалуу, анткени чыныгы жашоодо биз картаны окугучтун ичине дагы киргизебиз жана ал да анын бир бөлүгү болуп калат. Эстутум картасынан айырмаланып, адаптер компьютер менен жалпы интерфейске ээ. Бул USB кабели бар, башкача айтканда, ал USB аркылуу башка түзмөктөргө туташа алат. Ошондуктан, программада биздин класс CardReaderUSB интерфейсин ишке ашырат. Бирок бул ыкманын ичинде эмне болот? Жана бизге керек болгон нерсе болот! Адаптер ишти биздин эстутум картасына өткөрүп берет. Анткени, адаптер өзү эч нерсе кылbyte, картаны окугуч эч кандай көз карандысыз функцияга ээ эмес. Анын милдети компьютер менен эстутум картасын байланыштыруу гана, карта өз милдетин аткарып, файлдарды көчүрө алат! connectWithUsbCable()Биздин адаптер эстутум картасынын "муктаждыктары" үчүн өзүнүн интерфейсин (ыкмасын) камсыз кылуу менен муну жасоого мүмкүндүк берет . Эстутум картасынан маалыматтарды көчүрүүнү каалаган адамды окшоштурган кандайдыр бир кардар программасын түзөлү:
public class Main {

   public static void main(String[] args) {

       USB cardReader = new CardReader(new MemoryCard());
       cardReader.connectWithUsbCable();

   }
}
Натыйжада биз эмне алдык? Консолдук чыгаруу:
Карта памяти успешно вставлена!
Данные скопированы на компьютер!
Эң сонун, биздин тапшырма ийгorктүү аяктады! Бул жерде адаптер үлгүсү жөнүндө маалымат менен кээ бир кошумча шилтемелер:

Реферат класстары Окурман жана Жазуучу

Эми биз сүйүктүү убактыбызга кайтып келебиз: киргизүү жана чыгаруу менен иштөө боюнча бир нече жаңы сабактарды үйрөнөбүз :) Алардын канчасын үйрөндүк? Бүгүн биз класстар Readerжана Writer. Эмне үчүн алар жөнүндө? Анткени бул биздин мурунку бөлүмгө - адаптерлерге байланыштуу болот. Келгиле, аларды кененирээк карап көрөлү. Келгиле, Reader"а" менен баштайлы. Readerабстракттуу класс, ошондуктан биз анын an objectилерин ачык түзө албайбыз. Бирок, чындыгында, сиз аны мурунтан эле билесиз! Анткени, сиз жакшы билген класстар BufferedReaderанын InputStreamReaderмураскорлору :)
public class BufferedReader extends Reader {}

public class InputStreamReader extends Reader {}
Ошентип, класс InputStreamReaderклассикалык адаптер . Эсиңизде болсо керек, биз an objectти анын конструкторуна өткөрүп бере алабыз InputStream. Көбүнчө биз бул үчүн өзгөрмө колдонобуз System.in:
public static void main(String[] args) {

   InputStreamReader inputStreamReader = new InputStreamReader(System.in);
}
Ал эмне кылат InputStreamReader? Ар кандай адаптер сыяктуу эле, ал бир интерфейсти экинчисине айлантат. Бул учурда, интерфейс InputStream'a интерфейсине Reader' а. Башында классыбыз бар болчу InputStream. Ал жакшы иштейт, бирок ал жеке byteтарды гана окуй алат. Мындан тышкары, бизде абстракттуу класс бар Reader. Ал бизге абдан керектүү болгон эң сонун функцияга ээ - ал каармандарды окуй алат! Бизге, албетте, бул мүмкүнчүлүк абдан керек. Бирок бул жерде биз адаптерлер көбүнчө чечүүчү классикалык көйгөйгө туш болдук - интерфейстин туура келбестиги. Ал өзүн кантип көрсөтөт? Келгиле, түз Oracle documentтерин карап көрөлү. Бул жерде класстык ыкмалар InputStream. Паттерн проектирования «Адаптер» - 4Методдордун жыйындысы интерфейс болуп саналат. Көрүнүп тургандай, read()бул класстын методу бар (бир нече versionларда да), бирок ал byteтарды гана окуй алат: же жеке byte, же буферди колдонгон бир нече byte. Бул параметр бизге туура келбейт - биз каармандарды окугубуз келет. Бизге керектүү функция абстракттуу класста ишке ашырылганReader . Муну documentациядан да көрүүгө болот. Паттерн проектирования «Адаптер» - 5Бирок, InputStream"a" жана Reader"a" интерфейстери бири-бирине туура келбейт! Көрүнүп тургандай, бардык ыкмаларды ишке ашырууда read()өткөн параметрлер да, кайтаруу баалуулуктары да айырмаланат. Жана бул жерде бизге керек InputStreamReader! Ал биздин класстардын ортосунда Адаптер болуп иштейт . Биз жогоруда карап чыккан карта окугуч менен болгон мисалдагыдай эле, биз "адаптацияланган" класстын an objectисин "ички", башкача айтканда адаптер классынын конструкторуна өткөрүп беребиз. Мурунку мисалда биз an objectтин MemoryCardичине өттүк CardReader. Эми биз an objectти InputStreamконструкторго өткөрүп беребиз InputStreamReader! Сапат катары InputStreamбиз мурунтан эле тааныш өзгөрмө колдонобуз System.in:
public static void main(String[] args) {

   InputStreamReader inputStreamReader = new InputStreamReader(System.in);
}
Чынында эле: documentтерди карап, InputStreamReaderбиз "адаптация" ийгorктүү болгонун көрөбүз :) Эми каармандарды окууга мүмкүндүк берген ыкмаларыбыз бар. Паттерн проектирования «Адаптер» - 6Башында биздин an object System.in(клавиатурага байланган жип) буга жол бербесе да, Адаптер үлгүсүн түзүү менен тилди жаратуучулар бул маселени чечишти. Абстракттуу класс Reader, көпчүлүк I/O класстары сыяктуу эле, эгиз бир тууганы бар - Writer. Анын бир эле чоң артыкчылыгы бар Reader– ал символдор менен иштөө үчүн ыңгайлуу интерфейсти камсыз кылат. Чыгуу агымдары менен маселе жана анын чечими кириш агымындагыдай көрүнөт. OutputStreamБайттарды гана жаза турган класс бар ; Символдор менен иштей ала турган абстракттуу класс бар Writerжана бири-бирине дал келбеген эки интерфейс бар. Бул көйгөй кайрадан адаптер үлгүсү менен ийгorктүү чечилет. Классты колдонуу менен биз эки класс интерфейсин бири- бирине OutputStreamWriterоңой "ыңгайлаштыра" алабыз . Жана конструктордо byte агымын алгандан кийин, биз byteтарды эмес, символдорду жаза алабыз! WriterOutputStreamOutputStreamOutputStreamWriter
import java.io.*;

public class Main {

   public static void main(String[] args) throws IOException {

       OutputStreamWriter streamWriter = new OutputStreamWriter(new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt"));
       streamWriter.write(32144);
       streamWriter.close();
   }
}
Биз файлыбызга 32144 - 綐 codeу бар символду жаздык, ошентип byteтар менен иштөөнүн зарылдыгы жок болду :) Ушунун баары бүгүн, кийинки лекцияларда көрүшкөнчө! :)
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION