Паттерн Адаптер – структурный шаблон проектирования, предназначенный для организации использования функций объекта, недоступного для модификации, через специально созданный интерфейс. Паттерн адаптер предусматривает создание класса-оболочки с требуемым интерфейсом. Является, наверное, одним из самых часто употребляемых шаблонов проектирования, который можно встретить практически в любой программе, причем применяется программистами зачастую неосознанно и позволяет эффективно устранять проблему дублирования кода в определенных ситуациях. Одну из таких ситуаций мы рассмотрим далее.

Реализация: предположим, что мы работаем на заводе по производству машин в Германии и у нас есть интерфейс машин, которые мы производим:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
interface BasicCar{ public void drive(); public void xenonOn(); public void xenonOff(); } И класс, который реализует этот интерфейс реализует: class AudiA3 implements BasicCar{ final public int light = 100; @Override public void drive(){ System.out.println("AudiA3 rides!"); } @Override public void xenonOn(){ System.out.println("AudiA3 xenon on "); } @Override public void xenonOff(){ System.out.println("AudiA3 xenon off"); } } |
Как видим, наша машина умеет ездить, а еще у нее установлен ксенон которая она может включать и выключать. Всю работу по управлению ездой и фарами берет на себя центральный процессор машины:
1 2 3 4 5 6 7 8 9 10 11 12 |
class CentralProcessor{ private BasicCar car; public CentralProcessor(BasicCar car){ this.car = car; } public void work(){ car.drive(); car.xenonOn(); car.xenonOff(); } } |
В конструктор нашего процессора мы будем передавать объект созданной машины и вся магия будет происходить в методе work(), в котором мы поочередно будем вызывать все три метода реализованных в классе AudiA3 — drive(), xenonOn(), xenonOff(). Давайте понаблюдаем за работой нашей машины:
1 2 3 4 5 6 7 8 9 10 |
public class Example{ public static void main(String[] args){ //создаем объект машины BasicCar audiA3 = new AudiA3(); //создаем объект процессора и передаем ему в управления объект машины CentralProcessor cp = new CentralProcessor(audiA3); //процессор управляет работой машины cp.work(); } } |
Вывод:
AudiA3 rides!
AudiA3 xenon on
AudiA3 xenon off
Все работает просто и надежно как швейцарские часы. Но недавно мы узнали при запуске производства машин в России, был разработан другой класс машин, который учитывал национальные особенности, в частности в России запрещен ксенон и при производстве в машины устанавливаются обычные фары:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
interface BasicCarRus{ public void drive(); public void basicLightOn(); public void basicLightOff(); } class AudiA3Rus implements BasicCarRus{ final public int light = 50; @Override public void drive(){ System.out.println("AudiA3Rus rides!"); } @Override public void basicLightOn(){ System.out.println("AudiA3Rus basic light on"); } @Override public void basicLightOff(){ System.out.println("AudiA3Rus basic light off"); } } |
Как видим, методы управления машиной отличаются и у нас есть два варианта, создать новый класс процессора автомобиля или воспользоваться классом адаптером, мы выберем второй вариант:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class CarAdapter implements BasicCar{ BasicCarRus basicCarRus; public CarAdapter(BasicCarRus basicCarRus){ this.basicCarRus = basicCarRus; } @Override public void drive(){ basicCarRus.drive(); } @Override public void xenonOn(){ basicCarRus.basicLightOn(); } @Override public void xenonOff(){ basicCarRus.basicLightOff(); } } |
Класс адаптера реализует интерфейс базовой машины. Адаптируемый объект (в нашем случае машины, сделанные в России) мы передаем в конструкторе класса. Метод drive() абсолютно идентичен в машинах произведенных в Германии и России (AudiA3 и AudiA3Rus соответственно), поэтому мы просто в методе drive() запускаем метод drive() из класса AudiA3Rus:
1 |
basicCarRus.drive(); |
Так как в машины произведенные в России ксенон не устанавливается в методах xenonOn() и xenonOff() вступает в действие механизм адаптера – мы вызываем в них методы basicLightOn() и basicLightOff(). Давайте посмотрим, как это работает:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class Example{ public static void main(String[] args){ //создаем объект машины BasicCar audiA3 = new AudiA3(); //создаем объект процессора и передаем ему в управления объект машины CentralProcessor cp = new CentralProcessor(audiA3); //процессор управляет работой машины cp.work(); //cсоздаем адаптер и передаем в него машину CarAdapter audiA3Rus = new CarAdapter(new AudiA3Rus()); //создаем процессор и передаем в него адаптер CentralProcessor cpRus = new CentralProcessor(audiA3Rus); //процессор управляет машиной cpRus.work(); } } |
Вывод:
AudiA3 rides!
AudiA3 xenon on
AudiA3 xenon off
AudiA3Rus rides!
AudiA3Rus basic light on
AudiA3Rus basic light off
Как Вы можете заметить автомобильный процессор по прежнему запускает методы xenonOn() и xenonOff(), но благодаря классу-адаптеру на самом деле используются методы basicLightOn() и basicLightOff() класса AudiA3Rus.
Паттерн Адаптер полный код примера:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
package example; interface BasicCar{ public void drive(); public void xenonOn(); public void xenonOff(); } interface BasicCarRus{ public void drive(); public void basicLightOn(); public void basicLightOff(); } class AudiA3 implements BasicCar{ final public int light = 100; @Override public void drive(){ System.out.println("AudiA3 rides!"); } @Override public void xenonOn(){ System.out.println("AudiA3 xenon on "); } @Override public void xenonOff(){ System.out.println("AudiA3 xenon off"); } } class AudiA3Rus implements BasicCarRus{ final public int light = 50; @Override public void drive(){ System.out.println("AudiA3Rus rides!"); } @Override public void basicLightOn(){ System.out.println("AudiA3Rus basic light on"); } @Override public void basicLightOff(){ System.out.println("AudiA3Rus basic light off"); } } class CarAdapter implements BasicCar{ BasicCarRus basicCarRus; public CarAdapter(BasicCarRus basicCarRus){ this.basicCarRus = basicCarRus; } @Override public void drive(){ basicCarRus.drive(); } @Override public void xenonOn(){ basicCarRus.basicLightOn(); } @Override public void xenonOff(){ basicCarRus.basicLightOff(); } } class CentralProcessor{ private BasicCar car; public CentralProcessor(BasicCar car){ this.car = car; } public void work(){ car.drive(); car.xenonOn(); car.xenonOff(); } } public class Example{ public static void main(String[] args){ //создаем объект машины BasicCar audiA3 = new AudiA3(); //создаем объект процессора и передаем ему в управления объект машины CentralProcessor cp = new CentralProcessor(audiA3); //процессор управляет работой машины cp.work(); //cсоздаем адаптер и передаем в него машину CarAdapter audiA3Rus = new CarAdapter(new AudiA3Rus()); //создаем процессор и передаем в него адаптер CentralProcessor cpRus = new CentralProcessor(audiA3Rus); //процессор управляет машиной cpRus.work(); } } |