Patch адаптер: описание, функции и възможности, съвети за употреба

Адаптерът е структурен шаблон за проектиране, използван за организиране и прилагане на методи на обекти, които не могат да бъдат модифицирани чрез специално проектиран интерфейс. В противен случай може да се каже, че това е структурен модел, който позволява на обекти с несъвместими интерфейси да комуникират помежду си.

Описание

Адаптерът Patch извършва адаптиране между класове и обекти. Подобно на всеки адаптер в заобикалящия ни свят, шаблонът е интерфейс или мост между два обекта. В реалния свят имаме адаптери за захранващи устройства, за твърди дискове, за слушалки, за карти памет за фотоапарати и т.н. Нека разгледаме някои адаптери за карти с памет като пример. Ако не е възможно да свържете картата с памет на фотоапарата директно към преносимия компютър, можете да използвате адаптер: Картата с памет на фотоапарата се включва в адаптера, а адаптерът се включва в слота на преносимия компютър. По този начин ще бъде решен проблемът с несъвместимите интерфейси.

Адаптер: шаблон за проектиране и интерфейс

В случай на развитие в софтуера Това е приблизително същият начин. Можете да си представите ситуация, в която има клас, който очаква някакъв тип обект, и има обект, който предлага същата функционалност, но с различен интерфейс. Разбира се, би било изгодно да се използват и двата интерфейса, за да не се налага да се имплементира отново един от тях и да се модифицират съществуващите класове. Това е ситуация, в която е целесъобразно да се използва адаптер за проектиране на софтуер.

Изпълнение на

На фигурата по-долу е показана диаграма на класовете на адаптера на модела UML (UML).

Адаптер: UML диаграма

Класовете и обектите, включени в шаблона за проектиране:

  1. (Target) - определя специфичен за домейна интерфейс, който клиентът използва.
  2. (Адаптер) - адаптира интерфейса (Adaptee) към целевия интерфейс.
  3. (Приспособител - дефинира съществуващ интерфейс, който да бъде адаптиран.
  4. (Клиент) - взаимодейства с обекти, съответстващи на интерфейса (Цел).

Приложение

Шаблонът Adapter се използва в следните случаи

  • Когато има клас (Target), който извиква методи, дефинирани в интерфейса. Освен това има още един клас (Adapter), който не имплементира интерфейса, но реализира операции и методи, които се извикват от първия клас чрез интерфейса. Програмистът няма възможност да променя съществуващия код. Адаптерът имплементира своя интерфейс и се превръща в мост между двата класа.
Адаптер за кръпки: изграждане на проекта
  • Когато се пише клас (Target) за обща употреба, е важно да се разчита на някои общи интерфейси, а разработчикът има някои имплементирани класове, които не имплементират интерфейса. Също така този клас (Target) трябва да може да се извиква.

Добър пример за използване на адаптер биха били черупките, използвани за приемане на библиотеки и структури на трети страни: повечето приложения, използващи библиотеки на трети страни, използват адаптер като междинен слой между приложението и библиотеката на третата страна, за да отделят приложението от библиотеката. Ако трябва да се използва друга библиотека, е необходим само адаптер за новата библиотека, без да е необходимо да се променя кодът на приложението.

Адаптери за обекти на базата на делегиране

Обект (адаптер) е класически пример за шаблон на адаптер. Той използва композиция и (Adaptee) делегира повиквания към себе си, което не е достъпно за адаптерите на класове, които разширяват (Adaptee). Това поведение ни дава няколко предимства пред адаптерите на класове, но адаптерите на класове могат да се прилагат в езици, които позволяват многократно наследяване. Основното предимство е, че (Adapter) адаптира не само (Adaptee), но и всички негови подкласове. Всички тези подкласове съществуват с един "малък" ограничение: всички те не могат да добавят нови методи, тъй като използваният механизъм е делегиране. Следователно за всеки нов метод адаптерът трябва да бъде модифициран или разширен, за да предоставя нови методи. Основният недостатък е, че това изисква писането на нов код, който да делегира всички необходими заявки към адаптера.

Адаптери за класове, базирани на (многократно) наследяване

Адаптерите за класове могат да се реализират в езици, които поддържат многократно наследяване. Езиците за програмиране Java, C# и PHP не поддържат множествено наследяване, но имат интерфейси. Затова такива модели не могат да бъдат лесно реализирани на тези езици. Добър пример за език за програмиране, в който проектирането може да се реализира лесно, е C.

Шаблонът Adapter използва наследяване вместо композиция. Това означава, че вместо да делегира повиквания (Adaptee), той ги наследява. И накрая, адаптерът на класа трябва да е подклас както на (Target), така и на самия себе си (Adapter).

Адаптер, базиран на множествено наследяване

Този подход има своите предимства и недостатъци:

  • Моделът адаптира определен клас (Adaptee). Класът разширява тази адаптация. Ако е подклас, той не може да бъде адаптиран от съществуващ адаптер.
  • Моделът не изисква целия код, необходими за Делегация, която да бъде написана за класа (адаптер).
  • Ако даден обект (Target) е представен чрез интерфейс, а не чрез клас, можем да говорим за "клас" адаптери, защото можем да имплементираме толкова интерфейси, колкото искаме.

Двупосочни адаптери

Двупосочните адаптери са адаптери, които изпълняват както (Target), така и (Adaptee). Адаптираният обект може да се използва като (Target) в нови системи, работещи с класове (Target), или като (Adaptee) в други системи, работа с класове (Adaptee). Ако отидем още по-далеч в тази посока, можем да имаме адаптери, реализиращи n-броя интерфейси, които се адаптират към n-системи. Двупосочните адаптери и n-пътните адаптери са трудни за прилагане в системи, които не поддържат многократно наследяване. Ако даден адаптер трябва да разшири клас (Target), той не може да разшири друг клас, например (Adaptee), така че (Adaptee) трябва да бъде интерфейс и всички повиквания могат да бъдат делегирани от адаптера към обекта (Adaptee).

Използване на шаблона Adaptee при разработка на VR

Също така, ако (Target) и (Adapter) са сходни, тогава адаптерът трябва просто да делегира заявки от класа (Target) към класа (Adapter), а ако (Target) и (Adaptee) не са сходни, тогава може да се наложи адаптерът да преобразува структурите на данни между тях и да реализира операции, необходими за (Target), но нереализирани в класа (Adaptee).

Ето един пример за изпълнение

Да предположим, че имаме клас (Bird) с методи fly () и makeSound (). и клас (ToyDuck) с метод Squeak (). Да предположим, че имаме малко обекти (ToyDuck) и искаме да използваме обекти (Bird) вместо тях. Птиците имат подобна функционалност, но прилагат различен интерфейс, така че не можем да ги използваме директно. Затова ще използваме шаблон за адаптер. Тук нашият (Клиент) ще бъде (ToyDuck), а (Адаптиран) ще бъде (Bird). Ето един пример за реализация на шаблона за проектиране Adapter в Java, един от най-разпространените языков программирования.

interfaceBird{publicvoidfly();publicvoidmakeSound();}classSparrowimplementsBird{publicvoidfly(){System.out.println("Flying");}publicvoidmakeSound(){System.out.println("Chirp Chirp");}}interfaceToyDuck{publicvoidsqueak();}classPlasticToyDuckimplementsToyDuck{publicvoidsqueak(){System.out.println("Squeak");}}classBirdAdapterimplementsToyDuck{Bird bird;publicBirdAdapter(Bird bird){this.bird = bird;}publicvoidsqueak(){bird.makeSound();}}classMain{publicstaticvoidmain(String args[]){Sparrow sparrow =newSparrow();ToyDuck toyDuck =newPlasticToyDuck();ToyDuck birdAdapter =newBirdAdapter(sparrow);Система.на.println("Врабче...");врабче.муха();врабче.makeSound();Система.на.println("ToyDuck...");toyDuck.писък();Система.на.println("BirdAdapter...");birdAdapter.писък();}}

Да предположим, че имаме птица, която може да прави Sound (), и пластмасова играчка патица, която може да пищи - Squeak (). Сега да предположим, че нашият (Клиент) промени изискването и иска (ToyDuck) да изпълнява Sound (), но както?

Пример за проектиране, базиран на шаблона Adaptor

Решението е просто да се промени класът за изпълнение на нов клас адаптер и да се каже на клиента да предаде инстанция на птицата на този клас. Това е всичко. Сега, като променим само един ред, можем да научим (ToyDuck) да чурулика като врабче.

Статии по темата