Рубрики

Шаблон адаптера

Этот шаблон легко понять, так как реальный мир полон адаптеров. Например, рассмотрим переходник USB-Ethernet. Нам это нужно, когда у нас есть интерфейс Ethernet на одном конце и USB на другом. Так как они несовместимы друг с другом. мы используем адаптер, который преобразует один в другой. Этот пример довольно аналогичен объектно-ориентированным адаптерам. В дизайне адаптеры используются, когда у нас есть класс (Клиент), ожидающий некоторый тип объекта, и у нас есть объект (Адаптируемый), предлагающий те же функции, но представляющий другой интерфейс.

Чтобы использовать адаптер:

  1. Клиент делает запрос к адаптеру, вызывая метод на нем, используя целевой интерфейс.
  2. Адаптер транслирует этот запрос адаптеру, используя интерфейс адаптера.
  3. Клиент получает результаты звонка и не знает о наличии адаптера.

Определение:

Шаблон адаптера преобразует интерфейс класса в другой интерфейс, ожидаемый клиентами. Адаптер позволяет классам работать вместе, что иначе невозможно из-за несовместимых интерфейсов.

Диаграмма классов:

Клиент видит только целевой интерфейс, а не адаптер. Адаптер реализует целевой интерфейс. Адаптер делегирует все запросы адаптеру.

Пример:

Предположим, у вас есть класс Bird с методами fly () и makeSound (). А также класс ToyDuck с помощью метода squeak (). Давайте предположим, что у вас мало объектов ToyDuck и вы хотите использовать объекты Bird вместо них. Птицы имеют схожую функциональность, но реализуют другой интерфейс, поэтому мы не можем использовать их напрямую. Поэтому мы будем использовать шаблон адаптера. Здесь наш клиент будет ToyDuck, а Adaptee — Bird.

Ниже приведена Java-реализация.

// Java реализация шаблона адаптера

  

interface Bird

{

    // птицы реализуют интерфейс Bird, который позволяет

    // чтобы они летали и издавали звуки адаптивного интерфейса

    public void fly();

    public void makeSound();

}

  

class Sparrow implements Bird

{

    // конкретная реализация птицы

    public void fly()

    {

        System.out.println("Flying");

    }

    public void makeSound()

    {

        System.out.println("Chirp Chirp");

    }

}

  

interface ToyDuck

{

    // целевой интерфейс

    // игрушки не летают, они просто делают

    // скрипящий звук

    public void squeak();

}

  

class PlasticToyDuck implements ToyDuck

{

    public void squeak()

    {

        System.out.println("Squeak");

    }

}

  

class BirdAdapter implements ToyDuck

{

    // Вам нужно реализовать интерфейс вашего

    // клиент ожидает использования.

    Bird bird;

    public BirdAdapter(Bird bird)

    {

        // нам нужна ссылка на объект, который мы

        // адаптируем

        this.bird = bird;

    }

  

    public void squeak()

    {

        // переводим методы соответствующим образом

        bird.makeSound();

    }

}

  

class Main

{

    public static void main(String args[])

    {

        Sparrow sparrow = new Sparrow();

        ToyDuck toyDuck = new PlasticToyDuck();

  

        // Заворачиваем птицу в птичник, чтобы он

        // ведет себя как игрушка утка

        ToyDuck birdAdapter = new BirdAdapter(sparrow);

  

        System.out.println("Sparrow...");

        sparrow.fly();

        sparrow.makeSound();

  

        System.out.println("ToyDuck...");

        toyDuck.squeak();

  

        // игрушка утка ведёт себя как птица

        System.out.println("BirdAdapter...");

        birdAdapter.squeak();

    }

}

Выход:

Sparrow...
Flying
Chirp Chirp
ToyDuck...
Squeak
BirdAdapter...
Chirp Chirp

Пояснение:
Предположим, у нас есть птица, способная сделать Sound (), и пластиковая игрушечная утка, которая может пискнуть (). Теперь предположим, что наш клиент меняет требование и хочет, чтобы toyDuck сделал Sound, чем?
Простое решение состоит в том, что мы просто изменим класс реализации на новый класс адаптера и скажем клиенту передать экземпляр птицы (который хочет squeak ()) этому классу.
До: ToyDuck toyDuck = новый PlasticToyDuck ();
После: ToyDuck toyDuck = новый BirdAdapter (воробей);
Вы можете видеть, что, изменив только одну строку, toyDuck теперь может делать Chirp Chirp !!

Адаптер объекта против адаптера класса
Шаблон адаптера, который мы реализовали выше, называется Object Adapter Pattern, потому что адаптер содержит экземпляр adaptee. Существует также другой тип, называемый Class Adapter Pattern, в котором вместо композиции используется наследование, но для его реализации требуется множественное наследование.
Диаграмма классов шаблона адаптера класса:

Здесь вместо использования адаптивного объекта внутри адаптера (композиции) для использования его функциональных возможностей адаптер наследует адаптер.

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

Преимущества:

  • Помогает достичь повторного использования и гибкости.
  • Клиентский класс не сложен тем, что приходится использовать другой интерфейс и может использовать полиморфизм для переключения между различными реализациями адаптеров.

Недостатки:

  • Все запросы перенаправляются, поэтому накладные расходы незначительно увеличиваются.
  • Иногда для адаптации к требуемому типу требуется множество адаптаций по цепочке адаптеров.

Ссылки:
Head First Design Patterns (книга)

Эта статья предоставлена Сулабх Кумар. Если вам нравится GeeksforGeeks и вы хотите внести свой вклад, вы также можете написать статью и отправить ее по почте на contrib@geeksforgeeks.org. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.

Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой теме

Рекомендуемые посты:

Шаблон адаптера

0.00 (0%) 0 votes