JavaRush /Java Blog /Random-TL /Adapter ng Pattern ng Disenyo

Adapter ng Pattern ng Disenyo

Nai-publish sa grupo
Kamusta! Ngayon ay tatalakayin natin ang isang mahalagang bagong paksa - mga pattern, o sa madaling salita - mga pattern ng disenyo . Ano ang mga pattern? Sa tingin ko alam mo ang expression na "don't reinvent the wheel." Sa programming, tulad ng sa maraming iba pang mga lugar, mayroong isang malaking bilang ng mga tipikal na sitwasyon. Para sa bawat isa sa kanila, sa proseso ng pag-unlad ng programming, nilikha ang mga handa na solusyon sa pagtatrabaho. Ito ay mga pattern ng disenyo. Sa relatibong pagsasalita, ang isang pattern ay isang partikular na halimbawa na nag-aalok ng solusyon sa isang sitwasyon tulad ng: "kung may kailangang gawin ang iyong programa, kung paano ito pinakamahusay na gawin." Mayroong maraming mga pattern, isang mahusay na aklat na "Pag-aaral ng Mga Pattern ng Disenyo" ay nakatuon sa kanila, na dapat mong basahin. Pattern ng disenyo "Adapter" - 2Upang ilagay ito nang maikli hangga't maaari, ang isang pattern ay binubuo ng isang karaniwang problema at ang solusyon nito, na maaari nang ituring na isang uri ng pamantayan. Sa lektura ngayon ay makikilala natin ang isa sa mga pattern na ito na tinatawag na "Adapter". Ang pangalan nito ay nagsasabi, at nakatagpo ka ng mga adaptor sa totoong buhay nang higit sa isang beses. Ang isa sa mga pinaka-karaniwang adapter ay ang mga card reader, na nilagyan ng maraming mga computer at laptop. Pattern ng disenyo "Adapter" - 3Isipin na mayroon kaming ilang uri ng memory card. Ano ang problema? Ang katotohanan ay hindi niya alam kung paano makipag-ugnayan sa isang computer. Wala silang karaniwang interface. Ang computer ay may USB connector, ngunit hindi ka maaaring magpasok ng memory card dito. Ang card ay hindi maipasok sa computer, dahil dito hindi namin mai-save ang aming mga larawan, video at iba pang data. Ang card reader ay isang adaptor na lumulutas sa problemang ito. Pagkatapos ng lahat, mayroon itong USB cable! Hindi tulad ng card mismo, ang card reader ay maaaring ipasok sa isang computer. Mayroon silang karaniwang interface sa computer - USB. Tingnan natin kung ano ang magiging hitsura nito sa isang halimbawa:
public interface USB {

   void connectWithUsbCable();
}
Ito ang aming USB interface na ang tanging paraan ay ang pagpasok ng USB cable:
public class MemoryCard {

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

   public void copyData() {
       System.out.println("Данные скопированы на компьютер!");
   }
}
Ito ang aming klase na nagpapatupad ng memory map. Mayroon na itong 2 pamamaraan na kailangan namin, ngunit narito ang problema: hindi nito ipinapatupad ang USB interface. Ang card ay hindi maaaring ipasok sa USB slot.
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();
   }
}
At narito ang aming adaptor! Ano ang ginagawa ng klaseCardReader at bakit ito isang adaptor? Simple lang. Ang klase na iniangkop (memory map) ay nagiging isa sa mga field ng adapter. Ito ay lohikal, dahil sa totoong buhay ay nagpasok din kami ng isang card sa loob ng card reader, at ito rin ay nagiging bahagi nito. Hindi tulad ng isang memory card, ang adaptor ay may karaniwang interface sa computer. Mayroon itong USB cable, ibig sabihin maaari itong kumonekta sa iba pang mga device sa pamamagitan ng USB. Samakatuwid, sa programa, CardReaderipinapatupad ng aming klase ang USB interface. Ngunit ano ang nangyayari sa loob ng pamamaraang ito? At doon nangyayari ang eksaktong kailangan natin! Idelegate ng adapter ang trabaho sa aming memory card. Pagkatapos ng lahat, ang adaptor mismo ay walang ginagawa; ang card reader ay walang anumang independiyenteng pag-andar. Ang trabaho nito ay i-link lamang ang computer at ang memory card upang magawa ng card ang trabaho nito at makakopya ng mga file! Pinapayagan ito ng aming adaptor na gawin ito sa pamamagitan ng pagbibigay ng sarili nitong interface (paraan connectWithUsbCable()) para sa "mga pangangailangan" ng memory card. Gumawa tayo ng ilang uri ng programa ng kliyente na gayahin ang isang taong gustong kumopya ng data mula sa isang memory card:
public class Main {

   public static void main(String[] args) {

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

   }
}
Ano ang nakuha namin bilang isang resulta? Output ng console:
Карта памяти успешно вставлена!
Данные скопированы на компьютер!
Mahusay, matagumpay na natapos ang aming gawain! Narito ang ilang karagdagang link na may impormasyon tungkol sa pattern ng Adapter:

Abstract na klase Reader and Writer

Ngayon ay babalik tayo sa ating paboritong libangan: matututo tayo ng ilang bagong klase para sa pagtatrabaho sa input at output :) Ilan na sa kanila ang natutunan na natin, siguro? Ngayon ay pag-uusapan natin ang tungkol sa mga klase Readerat Writer. Bakit sa kanila? Dahil ito ay mauugnay sa aming nakaraang seksyon - mga adaptor. Tingnan natin ang mga ito nang mas detalyado. Magsimula tayo sa Reader'a. Readeray isang abstract na klase, kaya hindi namin malinaw na magagawa ang mga bagay nito. Pero sa totoo lang, kilala mo na siya! Pagkatapos ng lahat, ang mga klase na alam mo BufferedReaderay InputStreamReadermga tagapagmana nito :)
public class BufferedReader extends Reader {}

public class InputStreamReader extends Reader {}
Kaya, ang isang klase InputStreamReaderay isang klasikong adaptor . Tulad ng malamang na naaalala mo, maaari naming ipasa ang isang bagay sa constructor nito InputStream. Kadalasan, gumagamit kami ng variable para dito System.in:
public static void main(String[] args) {

   InputStreamReader inputStreamReader = new InputStreamReader(System.in);
}
Ano ang ginagawa nito InputStreamReader? Tulad ng anumang adaptor, nagko-convert ito ng isang interface sa isa pa. Sa kasong ito, ang interface InputStream'a sa interface Reader'a. Nung una may klase kami InputStream. Gumagana ito nang maayos, ngunit maaari lamang itong magbasa ng mga indibidwal na byte. Bilang karagdagan, mayroon kaming abstract na klase Reader. Mayroon itong mahusay na pag-andar na talagang kailangan namin - nakakabasa ito ng mga character! Siyempre, kailangan talaga natin ang pagkakataong ito. Ngunit narito tayo ay nahaharap sa isang klasikong problema na karaniwang nalulutas ng mga adaptor - hindi pagkakatugma ng interface. Paano ito nagpapakita ng sarili? Tingnan natin nang diretso ang dokumentasyon ng Oracle. Narito ang mga pamamaraan ng klase InputStream. Паттерн проектирования «Адаптер» - 4Ang isang hanay ng mga pamamaraan ay isang interface. Tulad ng nakikita mo, read()ang klase na ito ay may isang pamamaraan (kahit na sa ilang mga bersyon), ngunit maaari lamang itong magbasa ng mga byte: alinman sa mga indibidwal na byte, o ilang mga byte gamit ang isang buffer. Ang pagpipiliang ito ay hindi angkop sa amin - gusto naming basahin ang mga character. Ang pag-andar na kailangan namin ay ipinatupad na sa abstract na klaseReader . Makikita rin ito sa dokumentasyon. Паттерн проектирования «Адаптер» - 5Gayunpaman, ang InputStream'a' at Reader'a' na mga interface ay hindi magkatugma! Tulad ng nakikita mo, sa lahat ng mga pagpapatupad ng pamamaraan, read()ang mga naipasa na mga parameter at ang mga halaga ng pagbabalik ay naiiba. At ito ay kung saan kailangan namin ito InputStreamReader! Siya ang gaganap bilang Adapter sa pagitan ng aming mga klase. Tulad ng halimbawa sa card reader, na tiningnan namin sa itaas, ipinapasa namin ang bagay ng "inangkop" na klase "sa loob," iyon ay, sa tagabuo ng klase ng adaptor. Sa nakaraang halimbawa, ipinasa namin ang isang bagay MemoryCardsa loob CardReader. Ngayon ipinapasa namin ang bagay InputStreamsa tagabuo InputStreamReader! Bilang isang kalidad InputStreamginagamit namin ang pamilyar na variable System.in:
public static void main(String[] args) {

   InputStreamReader inputStreamReader = new InputStreamReader(System.in);
}
At sa katunayan: sa pamamagitan ng pagtingin sa dokumentasyon InputStreamReadermakikita natin na ang "pagbagay" ay matagumpay :) Ngayon ay mayroon na tayong mga pamamaraan sa pagtatapon na nagpapahintulot sa amin na magbasa ng mga character. Паттерн проектирования «Адаптер» - 6At kahit na sa una System.inay hindi ito pinayagan ng aming object (isang thread na nakatali sa keyboard), sa pamamagitan ng paglikha ng Adapter pattern, nalutas ng mga tagalikha ng wika ang problemang ito. Ang abstract class Reader, tulad ng karamihan sa I/O classes, ay may kambal na kapatid na lalaki - Writer. Ito ay may parehong malaking kalamangan Reader- nagbibigay ito ng isang maginhawang interface para sa pagtatrabaho sa mga simbolo. Sa mga output stream, ang problema at ang solusyon nito ay kapareho ng hitsura sa kaso ng mga input stream. Mayroong isang klase OutputStreamna maaari lamang magsulat ng mga byte; Mayroong isang abstract na klase Writerna maaaring gumana sa mga simbolo, at mayroong dalawang hindi magkatugma na mga interface. Ang problemang ito ay muling matagumpay na nalutas ng Adapter pattern. Gamit ang isang klase, OutputStreamWritermadali nating "maaangkop" ang dalawang interface ng klase Writersa OutputStreamisa't isa. At, na nakatanggap ng isang byte stream OutputStreamsa constructor, sa tulong na OutputStreamWritermaaari naming, gayunpaman, magsulat ng mga character, hindi bytes!
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();
   }
}
Sumulat kami ng isang character na may code 32144 - 綐 sa aming file, kaya inaalis ang pangangailangan na magtrabaho sa mga byte :) Iyon lang para sa araw na ito, magkita-kita tayo sa mga susunod na lektura! :)
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION