когда нам нужен шаблон адаптера? - PullRequest
23 голосов
/ 13 августа 2010

Когда нам нужно перейти к шаблону адаптера? Если возможно, приведите пример из реальной жизни, соответствующий этому шаблону ...

Ответы [ 6 ]

43 голосов
/ 14 августа 2010

Я работал в системе, которая должна была взаимодействовать с внешними видеорегистраторами.По большей части все DVR имеют одинаковую базовую функциональность: начать запись с определенного источника видео;остановить запись;начать воспроизведение с определенного времени;остановка воспроизведения и т. д.

Каждый производитель видеорегистратора предоставил библиотеку программного обеспечения, позволяющую нам писать код для управления своим устройством (для обсуждения я буду называть его SDK).Несмотря на то, что каждый SDK предоставлял API для всех основных функций, ни один из них не был совершенно одинаковым.Вот очень грубый пример, но вы получите идею:

  • BeginPlayback (DateTime startTime);
  • StartPlayback (long startTimeTicks);
  • Воспроизведение (string startDate,string startTime);

Наше программное обеспечение должно было взаимодействовать со всеми видеорегистраторами.Поэтому вместо того, чтобы писать ужасные переключатели / случаи для каждого отдельного SDK, мы создали собственный общий интерфейс IDVRController и записали весь наш системный код в этот интерфейс:

  • Воспроизведение (DateTime startTime);

Затем мы написали разные реализации адаптера для каждого SDK, каждый из которых реализовал наш интерфейс IDVRController.Мы использовали файл конфигурации, чтобы указать тип DVR, к которому будет подключаться система, и шаблон Factory, чтобы создать экземпляр правильной реализации IDVRController для этого DVR.

Таким образом, шаблон адаптера сделал наш системный код проще: мы всегда кодировали IDVRController.И это позволило нам развернуть адаптеры для новых SDK после развертывания (наша Фабрика использовала отражение для создания экземпляра правильного экземпляра IDVRController).

4 голосов
/ 16 июля 2015

Существующий интерфейс

interface Shape {
    public int calculateArea(int r);
}

Текущая реализация для интерфейса Shape

class Square implements Shape {
    @Override
    public int calculateArea(int r) {
        return r * r;
    }
}

Теперь учтите, что вы хотите, чтобы класс Circle адаптировался к нашему существующему интерфейсу, который мы никак не можем изменить (Написано третьей стороной).

class Circle {
    public double calculateCircularArea (int r) {
        return 3.14 * r * r;
    }
}

Теперь мы адаптировали реализацию Circle к нашему интерфейсу Shape. Поэтому нам нужен адаптер, так как они несовместимы.

class CirCleAdaptor extends Circle implements Shape {
    @Override
    public int calculateArea(int r) {
        return (int) calculateCircularArea(r);
    }
}

CircleAdaptor - это адаптер для круга
Круг - это Адаптированный
Форма - это целевой интерфейс

public class AdapterPattern {
    public static void main(String[] args) {
        Shape circle = new CirCleAdaptor();
        System.out.println("Circle Area " + circle.calculateArea(5));
        Shape square = new Square();
        System.out.println("Square Area " + square.calculateArea(5));
    }
}

Надеюсь, это даст лучшее представление о том, когда его использовать.

4 голосов
/ 13 августа 2010

В компьютерном программировании шаблон адаптера (часто называемый шаблоном обертки или просто оберткой) является шаблоном проектирования, который переводит один интерфейс для класса в совместимый интерфейс.Адаптер позволяет классам работать вместе, что обычно невозможно из-за несовместимых интерфейсов, предоставляя его интерфейс клиентам при использовании исходного интерфейса.Адаптер переводит вызовы к своему интерфейсу в вызовы к исходному интерфейсу, и объем кода, необходимый для этого, обычно невелик.Адаптер также отвечает за преобразование данных в соответствующие формы.Например, если несколько логических значений хранятся как одно целое число, но ваш потребитель требует 'true' / 'false', адаптер будет ответственен за извлечение соответствующих значений из целочисленного значения.alt text

Википедия !!!

3 голосов
/ 21 февраля 2018

Вы можете использовать шаблон проектирования адаптера, когда вам приходится иметь дело с различными интерфейсами с похожим поведением (что обычно означает классы с похожим поведением, но с разными методами).Примером этого может быть класс для подключения к телевизору Samsung, а другой - для подключения к телевизору Sony.Они будут иметь общее поведение, такое как открытое меню, запуск воспроизведения, подключение к сети и т. Д., Но каждая библиотека будет иметь свою реализацию (с разными именами методов и сигнатурами).Эти реализации для разных поставщиков называются Adaptee на диаграммах UML.

Итак, в вашем коде (называемом Client на диаграммах UML) вместо жесткого кодаВ вызовах методов каждого поставщика (или Adaptee ) вы можете создать универсальный интерфейс (называемый Target на диаграммах UML), чтобы обернуть эти сходные поведения и работать только с одним типом объекта.

Адаптеры будут затем реализовывать интерфейс Target , делегируя свои вызовы методов Adaptees , которые передаются в Адаптеры via constructor.

Чтобы вы могли реализовать это в коде Java, я написал очень простой проект, использующий точно такой же пример, упомянутый выше, с использованием адаптеров для работы с несколькими интерфейсами Smart TV.Код небольшой, хорошо документированный и не требует пояснений, поэтому покопайтесь в нем, чтобы увидеть, как будет выглядеть реальная реализация.

Просто скачайте код и импортируйте его в Eclipse (или вашу любимую IDE) в качестве проекта Maven.,Вы можете выполнить код, запустив org.example.Main.java .Помните, что здесь важно понимать, как классы и интерфейсы собираются вместе для разработки шаблона.Я также создал несколько поддельных Adaptees в пакете com.thirdparty.libs .Надеюсь, это поможет!

https://github.com/Dannemann/java-design-patterns

2 голосов
/ 11 октября 2013

Шаблон адаптера требуется в следующем сценарии:

Допустим, вы определили интерфейс I1 с методом M1 и M2

C1 и C2 реализует этоинтерфейс I1, теперь для C1 при реализации M1 и M2 вы не нашли помощи от других существующих классов, поэтому вам нужно написать всю логику самостоятельно.

Теперь при реализации класса C2 вы столкнулись с классом C3 с методами M3 и M4, которые можно использовать для реализации M1 и M2 для C2, чтобы использоватьте M3 и M4 в классе C2 вы расширяете класс C3 и используете M3 и M4 из C3.

В этом примере C2 становится Adapter class иC3 становится adaptee

package com.design.patterns;

public class AdapterExample {
    public static void main(String[] args) {
        Shape line = new LineShape();
        line.draw();

        Shape text = new TextShape();
        text.draw();
    }
}

//==Start from here
interface Shape{
    public void draw();
}

class LineShape implements Shape{
    @Override
    public void draw() {
        System.out.println("write some logic and draw line");
    }   
}

//Adapter
class TextShape extends TextView implements Shape{
    @Override
    public void draw() {
        System.out.println("logic is already there in class TextView");
        drawText();
    }   
}

// Adaptee
class TextView{
    public void drawText() {
        System.out.println("Drawing Text Shape");
    }
}
1 голос
/ 21 февраля 2018

Очень распространенный пример шаблона адаптера выполняется через Интерфейс поставщика услуг и обычно используется во многих средах Java EE.

Причина этого заключается в разрешенииразличные реализации Java EE, но программисты просто кодируют в спецификацию Java EE, а не что-то конкретное для реализации.

В отличие от чего-то вроде непосредственного кодирования с использованием классов WebSphere, которое привязывает вас к использованию WebSphere.

Илихуже (из моего опыта), Apache HTTP Client и узнаю позже, что, поскольку вы закодировали эту реализацию, а не обычное HttpUrlConnection, вам придется много перекодировать, потому что он не поддерживает текущую версию TLS, которую можно было бы избежатьесли первоначальный разработчик закодировал более стабильный API, и нам просто нужно обновить среду выполнения Java.

...