JavaRush /Java блогы /Random-KK /Дизайн үлгісінің адаптері

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

Топта жарияланған
Сәлеметсіз бе! Бүгін біз маңызды жаңа тақырыпты қозғаймыз - үлгілер, немесе басқаша айтқанда - дизайн үлгілері . Үлгілер дегеніміз не? Менің ойымша, сіз «дөңгелекті қайта ойлап таппаңыз» деген сөзді білесіз. Бағдарламалауда, көптеген басқа салалардағы сияқты, типтік жағдайлардың үлкен саны бар. Олардың әрқайсысы үшін бағдарламалауды әзірлеу барысында дайын жұмыс шешімдері жасалды. Бұл дизайн үлгілері. Салыстырмалы түрде айтқанда, үлгі - бұл жағдайдың шешімін ұсынатын белгілі бір мысал: «егер сіздің бағдарламаңызға бірдеңе жасау керек болса, оны қалай жақсы істеу керек». Көптеген үлгілер бар, оларға «Дизайн үлгілерін зерттеу» тамаша кітабы арналған, сіз оны міндетті түрде оқуыңыз керек. Дизайн үлгісі «Адаптер» - 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 интерфейсін жүзеге асырмайды. Картаны 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 интерфейсін жүзеге асырады. Бірақ бұл әдістің ішінде не болады? Және дәл бізге қажет нәрсе болады! Адаптер жұмысты біздің жад картасына тапсырады. Ақыр соңында, адаптердің өзі ештеңе жасамайды, картаны оқу құрылғысында тәуелсіз функция жоқ. Оның жұмысы тек компьютер мен жад картасын байланыстыру болып табылады, осылайша карта өз жұмысын орындап, файлдарды көшіре алады! connectWithUsbCable()Біздің адаптер жад картасының «қажеттіліктері» үшін өз интерфейсін (әдісін) қамтамасыз ету арқылы мұны істеуге мүмкіндік береді . Жад картасынан деректерді көшіргісі келетін адамға ұқсайтын клиенттік бағдарламаның қандай да бір түрін жасайық:
public class Main {

   public static void main(String[] args) {

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

   }
}
Нәтижесінде не алдық? Консоль шығысы:
Карта памяти успешно вставлена!
Данные скопированы на компьютер!
Керемет, біздің тапсырма сәтті орындалды! Мұнда адаптер үлгісі туралы ақпарат бар кейбір қосымша сілтемелер берілген:

Реферат сыныптары Оқырман және Жазушы

Енді біз сүйікті ісімізге қайта ораламыз: біз енгізу және шығарумен жұмыс істеуге арналған бірнеше жаңа сабақтарды үйренеміз :) Олардың қаншасын үйрендік, қызық? Бүгін біз сабақтар туралы Readerжәне Writer. Неліктен олар туралы? Өйткені бұл біздің алдыңғы бөлімімізге - адаптерлерге қатысты болады. Оларды толығырақ қарастырайық. 'a- дан бастайық Reader. Readerабстрактілі класс, сондықтан біз оның нысандарын анық жасай алмаймыз. Бірақ шын мәнінде, сіз оны бұрыннан білесіз! Өйткені, сіз жақсы білетін сыныптар 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' a. Бастапқыда бізде сынып болды InputStream. Ол жақсы жұмыс істейді, бірақ ол тек жеке byteтарды оқи алады. Сонымен қатар, бізде дерексіз класс бар Reader. Оның бізге өте қажет функционалдығы бар - ол кейіпкерлерді оқи алады! Бұл мүмкіндік бізге, әрине, өте қажет. Бірақ бұл жерде адаптерлер әдетте шешетін классикалық мәселеге тап болдық - интерфейстің үйлесімсіздігі. Ол өзін қалай көрсетеді? Oracle құжаттамасын тікелей қарастырайық. Міне, сынып әдістері InputStream. Паттерн проектирования «Адаптер» - 4Әдістердің жиынтығы интерфейс болып табылады. Көріп отырғаныңыздай, read()бұл сыныптың әдісі бар (тіпті бірнеше нұсқаларда), бірақ ол тек byteтарды оқи алады: жеке byte немесе буфер арқылы бірнеше byte. Бұл опция бізге сәйкес келмейді - біз кейіпкерлерді оқығымыз келеді. Бізге қажет функционалдылық абстрактілі сыныпта қазірдің өзінде енгізілгенReader . Мұны құжаттамадан да көруге болады. Паттерн проектирования «Адаптер» - 5Дегенмен, InputStream«a» және Reader«a» интерфейстері үйлесімсіз! Көріп отырғаныңыздай, барлық әдісті іске асыруда read()берілген параметрлер де, қайтару мәндері де ерекшеленеді. Бұл бізге керек жер InputStreamReader! Ол біздің сыныптар арасында адаптер ретінде әрекет етеді . Біз жоғарыда қарастырған карта оқу құралымен мысалдағыдай, біз «бейімделген» класс an objectісін «ішкі», яғни адаптер класының конструкторына береміз. Алдыңғы мысалда біз MemoryCardішіндегі нысанды өткіздік CardReader. InputStreamЕнді an objectіні конструкторға береміз InputStreamReader! Сапа ретінде InputStreamбіз бұрыннан таныс айнымалыны қолданамыз System.in:
public static void main(String[] args) {

   InputStreamReader inputStreamReader = new InputStreamReader(System.in);
}
Шынында да: құжаттаманы қарап отырып, InputStreamReaderбіз «бейімдеудің» сәтті болғанын көреміз :) Енді кейіпкерлерді оқуға мүмкіндік беретін әдістер біздің қолымызда. Паттерн проектирования «Адаптер» - 6Алғашында біздің нысан System.in(пернетақтаға байланыстырылған жіп) бұған мүмкіндік бермесе де, адаптер үлгісін жасау арқылы тіл жасаушылар бұл мәселені шешті. Көптеген енгізу/шығару кластары сияқты абстрактілі сыныптың Readerегіз ағасы бар - Writer. Оның бірдей үлкен артықшылығы бар Reader- ол символдармен жұмыс істеуге ыңғайлы интерфейсті қамтамасыз етеді. Шығару ағындарымен мәселе және оның шешімі кіріс ағындарымен бірдей көрінеді. OutputStreamТек byteты жаза алатын класс бар ; WriterСимволдармен жұмыс істей алатын абстрактілі класс бар және үйлеспейтін екі интерфейс бар. Бұл мәселе қайтадан адаптер үлгісі арқылы сәтті шешілді. Классты пайдалана отырып, біз екі сынып интерфейсін бір -біріне 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