JavaRush /Java blogi /Random-UZ /Dizayn namunasi adapteri

Dizayn namunasi adapteri

Guruhda nashr etilgan
Salom! Bugun biz muhim yangi mavzuga to'xtalamiz - naqshlar, yoki boshqacha qilib aytganda - dizayn naqshlari . Shakllar nima? O'ylaymanki, siz "g'ildirakni qayta ixtiro qilmang" iborasini bilasiz. Dasturlashda, boshqa ko'plab sohalarda bo'lgani kabi, juda ko'p tipik vaziyatlar mavjud. Ularning har biri uchun dasturlashni ishlab chiqish jarayonida tayyor ishchi yechimlar yaratilgan. Bu dizayn naqshlari. Nisbatan aytganda, naqsh bu vaziyatga yechim taklif qiladigan ma'lum bir misol: "agar sizning dasturingiz biror narsa qilish kerak bo'lsa, buni qanday qilish kerak". Naqshlar juda ko'p, ularga "Dizayn naqshlarini o'rganish" ajoyib kitobi bag'ishlangan, siz albatta o'qishingiz kerak. Dizayn namunasi "Adapter" - 2Iloji boricha qisqacha aytganda, naqsh umumiy muammo va uning echimidan iborat bo'lib, uni allaqachon o'ziga xos standart deb hisoblash mumkin. Bugungi ma'ruzamizda ana shunday naqshlardan biri "Adapter" bilan tanishamiz. Uning nomi aytib turibdi va siz real hayotda adapterlarga bir necha bor duch kelgansiz. Eng keng tarqalgan adapterlardan biri kartani o'qish moslamalari bo'lib, ular ko'plab kompyuterlar va noutbuklar bilan jihozlangan. Adapter dizayni namunasi - 3Tasavvur qiling-a, bizda qandaydir xotira kartasi bor. Qanday muammo mavjud? Gap shundaki, u kompyuter bilan qanday ishlashni bilmaydi. Ularning umumiy interfeysi yo'q. Kompyuterda USB ulagichi bor, lekin siz unga xotira kartasini joylashtira olmaysiz. Kartani kompyuterga kiritish mumkin emas, shuning uchun biz fotosuratlarimiz, videolarimiz va boshqa ma'lumotlarni saqlay olmaymiz. Karta o'quvchi - bu muammoni hal qiladigan adapter. Axir, uning USB kabeli bor! Kartaning o'zidan farqli o'laroq, kartani o'quvchi kompyuterga kiritilishi mumkin. Ular kompyuter bilan umumiy interfeysga ega - USB. Keling, misol bilan qanday ko'rinishini ko'rib chiqaylik:
public interface USB {

   void connectWithUsbCable();
}
Bu bizning USB interfeysimiz bo'lib, USB kabelini ulashning yagona usuli:
public class MemoryCard {

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

   public void copyData() {
       System.out.println("Данные скопированы на компьютер!");
   }
}
Bu xotira xaritasini amalga oshiradigan bizning sinfimiz. U allaqachon bizga kerak bo'lgan 2 ta usulga ega, ammo muammo bu erda: u USB interfeysini amalga oshirmaydi. Kartani USB uyasiga kiritish mumkin emas.
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();
   }
}
Va bu bizning adapterimiz! SinfCardReader nima qiladi va nima uchun u adapter? Hammasi oddiy. Moslashtirilayotgan sinf (xotira xaritasi) adapterning maydonlaridan biriga aylanadi. Bu mantiqan to'g'ri, chunki real hayotda biz kartani o'quvchi ichiga ham joylashtiramiz va u ham uning bir qismiga aylanadi. Xotira kartasidan farqli o'laroq, adapter kompyuter bilan umumiy interfeysga ega. U USB kabeliga ega, ya'ni USB orqali boshqa qurilmalarga ulanishi mumkin. Shuning uchun, dasturda bizning sinfimiz CardReaderUSB interfeysini amalga oshiradi. Ammo bu usul ichida nima sodir bo'ladi? Va aynan bizga kerak bo'lgan narsa sodir bo'ladi! Adapter ishni xotira kartamizga topshiradi. Axir, adapterning o'zi hech narsa qilmaydi, kartani o'quvchi mustaqil funktsiyaga ega emas. Uning vazifasi faqat kompyuter va xotira kartasini bog'lashdir, shunda karta o'z ishini bajarishi va fayllarni nusxalashi mumkin! connectWithUsbCable()Bizning adapterimiz xotira kartasining "ehtiyojlari" uchun o'z interfeysini (usulini) taqdim etish orqali buni amalga oshirishga imkon beradi . Keling, xotira kartasidan ma'lumotlarni ko'chirmoqchi bo'lgan odamni taqlid qiladigan mijoz dasturini yarataylik:
public class Main {

   public static void main(String[] args) {

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

   }
}
Natijada nimaga erishdik? Konsol chiqishi:
Карта памяти успешно вставлена!
Данные скопированы на компьютер!
Ajoyib, bizning vazifamiz muvaffaqiyatli bajarildi! Adapter namunasi haqidagi ma'lumotlarga ega ba'zi qo'shimcha havolalar:

Referat darslari Reader va Writer

Endi biz sevimli mashg'ulotimizga qaytamiz: kiritish va chiqish bilan ishlash uchun bir nechta yangi darslarni o'rganamiz :) Ulardan qanchasini biz allaqachon o'rganganmiz, hayronman? Bugun biz darslar haqida gaplashamiz Readerva Writer. Nega ular haqida? Chunki bu bizning oldingi bo'limimiz - adapterlar bilan bog'liq bo'ladi. Keling, ularni batafsil ko'rib chiqaylik. Keling, Reader"a" bilan boshlaylik. Readerbu mavhum sinf, shuning uchun biz uning ob'ektlarini aniq yarata olmaymiz. Ammo, aslida, siz uni allaqachon bilasiz! Axir siz yaxshi biladigan sinflar BufferedReaderuning InputStreamReadermerosxo'rlari :)
public class BufferedReader extends Reader {}

public class InputStreamReader extends Reader {}
Shunday qilib, sinf InputStreamReaderklassik adapterdir . Esingizda bo'lsa kerak, biz ob'ektni uning konstruktoriga o'tkazishimiz mumkin InputStream. Buning uchun ko'pincha o'zgaruvchidan foydalanamiz System.in:
public static void main(String[] args) {

   InputStreamReader inputStreamReader = new InputStreamReader(System.in);
}
Bu nima qiladi InputStreamReader? Har qanday adapter singari, u bir interfeysni boshqasiga o'zgartiradi. Bunday holda, interfeys InputStream'a interfeysiga Reader' a. Dastlab bizda dars bor edi InputStream. U yaxshi ishlaydi, lekin u faqat alohida baytlarni o'qiy oladi. Bundan tashqari, bizda abstrakt sinf mavjud Reader. U bizga juda kerak bo'lgan ajoyib funksionallikka ega - u belgilarni o'qiy oladi! Albatta, bu imkoniyat bizga juda kerak. Ammo bu erda biz adapterlar odatda hal qiladigan klassik muammoga duch kelamiz - interfeysning mos kelmasligi. U o'zini qanday namoyon qiladi? Keling, to'g'ridan-to'g'ri Oracle hujjatlarini ko'rib chiqaylik. Bu erda sinf usullari InputStream. Паттерн проектирования «Адаптер» - 4Usullar to'plami - bu interfeys. Ko'rib turganingizdek, read()bu sinfning usuli mavjud (hatto bir nechta versiyalarda ham), lekin u faqat baytlarni o'qiy oladi: alohida baytlar yoki bufer yordamida bir necha bayt. Ushbu parametr bizga mos kelmaydi - biz belgilarni o'qishni xohlaymiz. Bizga kerak bo'lgan funksionallik allaqachon mavhum sinfda amalga oshirilganReader . Buni hujjatlarda ham ko'rish mumkin. Паттерн проектирования «Адаптер» - 5Biroq, InputStream"a" va Reader"a" interfeyslari mos kelmaydi! Ko'rib turganingizdek, barcha usullarni qo'llashda read()o'tgan parametrlar ham, qaytarish qiymatlari ham farqlanadi. Va bu bizga kerak bo'lgan joy InputStreamReader! U bizning sinflarimiz orasida Adapter vazifasini bajaradi . Biz yuqorida ko'rib chiqqan kartani o'quvchi misolida bo'lgani kabi, biz "moslashtirilgan" sinf ob'ektini "ichki", ya'ni adapter sinfining konstruktoriga o'tkazamiz. Oldingi misolda biz ob'ektni MemoryCardichiga o'tkazdik CardReader. Endi biz ob'ektni InputStreamkonstruktorga o'tkazamiz InputStreamReader! Sifat sifatida InputStreambiz allaqachon tanish bo'lgan o'zgaruvchidan foydalanamiz System.in:
public static void main(String[] args) {

   InputStreamReader inputStreamReader = new InputStreamReader(System.in);
}
Va haqiqatan ham: hujjatlarni ko'rib chiqsak, InputStreamReaderbiz "moslashish" muvaffaqiyatli bo'lganini ko'ramiz :) Endi bizda belgilarni o'qishga imkon beradigan usullar mavjud. Паттерн проектирования «Адаптер» - 6Garchi dastlab bizning ob'ektimiz System.in(klaviaturaga bog'langan ip) bunga yo'l qo'ymasa ham, Adapter naqshini yaratish orqali til yaratuvchilari bu muammoni hal qilishdi. Abstrakt sinf Reader, ko'pgina kiritish-chiqarish sinflari kabi, egizak akasi bor - Writer. U xuddi shunday katta afzalliklarga ega Reader- u belgilar bilan ishlash uchun qulay interfeysni taqdim etadi. Chiqish oqimlari bilan muammo va uning yechimi kirish oqimlaridagi kabi ko'rinadi. OutputStreamFaqat bayt yozish mumkin bo'lgan sinf mavjud ; Belgilar bilan ishlay oladigan mavhum sinf mavjud Writerva ikkita mos kelmaydigan interfeys mavjud. Ushbu muammo yana adapter namunasi bilan muvaffaqiyatli hal qilindi. Sinfdan foydalanib, biz ikkita sinf interfeysini bir- biriga OutputStreamWriterosongina "moslashtira olamiz" . Va konstruktorda bayt oqimini olganimizdan so'ng , biz yordam bilan baytlarni emas, balki belgilarni yozishimiz mumkin! 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();
   }
}
Biz faylimizga 32144 - lín kodli belgi yozdik, shu bilan baytlar bilan ishlash zaruratini yo'qotdik :) Bugun hammasi shu, keyingi ma'ruzalarda ko'rishguncha! :)
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION