[Серия «Учимся вместе»] Режим адаптера: и режим внешнего вида?

Шаблоны проектирования
[Серия «Учимся вместе»] Режим адаптера: и режим внешнего вида?

режим адаптера

намерение

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

Псевдоним: Обертка

Рождение шаблона адаптера

【Продукт】: Брат разработчик, вы помните наши требования к первой версии?

[Развитие]: Что это?

[Продукт]: В первой версии мы сделали много уток? Теперь нужно сделать маленькую индейку, но заказчик очень странный. Они хотят, чтобы у утки были такие же способности, как у индейки. Что нам делать?

[В разработке]: Написать утку как индейку?

【Продукт】: Нет, индюки - это индюки, а утки - это утки. Только в особых случаях их нужно смешивать вместе. Что мне делать?

[Развитие]: босс, как это сделать?

[БОСС]: Что за индюки, у них разве нет своих интерфейсов, два интерфейса просто сделаны с переходниками, иди проверь информацию сам!

Основной код HeadFirst

Согласно вышеизложенному, мы хотя бы немного знаем, нужны ли вам два интерфейса для игры в режиме адаптера? Сначала будь вопросом, мы поговорим об этом позже

"утиный интерфейс"

/**
 * 鸭子接口
 */
public interface Duck {
    /**
     * 鸭叫
     */
    void quack();

    /**
     * 飞行
     */
    void fly();
}

"Интерфейс Турции"

/**
 * 火鸡接口
 */
public interface Turkey {
    /**
     * 火鸡叫
     */
    void gobble();

    /**
     * 飞行
     */
    void fly();
}

"Класс реализации Турции"

/**
 * 火鸡实现类
 */
public class WildTurkey implements Turkey{
    @Override
    public void gobble() {
        System.out.println("咯咯");
    }

    @Override
    public void fly() {
        System.out.println("我在飞,虽然我飞的很近");
    }
}

"Ключевой момент! приспособление!"

/**
 * 火鸡适配器
 * 实现鸭子接口同时持有火鸡对象,在实现的接口处用火鸡对象的方法填充一下(同时还可以做额外的事情)
 */
public class TurkeyAdapter implements Duck{

    Turkey turkey;

    @Override
    public void quack() {
        turkey.gobble();
    }

    @Override
    public void fly() {
        turkey.fly();
    }

    public TurkeyAdapter(Turkey turkey) {
        this.turkey = turkey;
    }
}

Идеи оформления выкройки адаптера:

  • Цель определяет специфичные для домена интерфейсы
  • Объект клиента, соответствующий целевому интерфейсу
  • Adaptee определяет существующий интерфейс, который необходимо адаптировать
  • Адаптер адаптер

Проще говоря, когда нам нужно смешать два несвязанных интерфейса, нам нужно использовать адаптер для реализации интерфейса A, удерживать объект B, а затем использовать метод объекта B для заполнения метода интерфейса A, и мы также можем добавить некоторые другие логика

Он очень похож на декоратор?

С точки зрения владения языками программирования они действительно очень похожи, разберем их сходства и различия:

"Тот же пункт:"

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

"разница:"

  • Количество интерфейсов разное, декоратор, как правило, представляет собой один интерфейс, а адаптер представляет собой смесь более двух интерфейсов.
  • Цель другая, декоратор — улучшить методы объекта, а адаптер — заставить работать вместе интерфейсы, которые не могут работать вместе

Приходите на волну интерфейсных адаптеров

Интерфейсные адаптеры очень распространены в Java, например: MouseListener и MouseAdapter.

Например:

/**
 * 定义超多的方法
 */
public interface InterfaceClass {
    void a();
    void b();
    void c();
    void d();
    void e();
    void f();
}

Используйте абстрактный класс для реализации интерфейса:

public abstract class InterfaceAdapter implements InterfaceClass{

    @Override
    public void a() {
        System.out.println("i have override method a");
    }

    @Override
    public void b() {}

    @Override
    public void c() {}

    @Override
    public void d() {}

    @Override
    public void e() {}

    @Override
    public void f() {}
}

Какова польза от этого? Например, Mouseadapter, мы, должно быть, использовали его, когда мы изучали программирование GUI. В это время я просто хочу переписать метод щелчка, но если вы напрямую используете интерфейс, есть слишком много кода, и вам нужно переписать Много вещей. Если вы используете интерфейсный адаптер, то вы можете легко уменьшить множество бесполезных кодов и сосредоточиться на методе, который вы хотите достичь

какие сценарии применяются

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

Код / практическое применение в жизни

В настоящее время мобильные телефоны стремятся к полному экрану. Необходим адаптер между телефоном Android и гарнитурой. В настоящее время адаптер является адаптером. Он удерживает объект гарнитуры и реализует интерфейс разъема для мобильного телефона. Последняя функция по-прежнему гарнитура, но она соединяет объекты, которые в противном случае не были бы связаны

UML-диаграмма

Внешний вид Режим

намерение

Предоставляя согласованный интерфейс для набора интерфейсов в подсистеме, шаблон Facade определяет высокоуровневый интерфейс, упрощающий использование подсистемы.

"Основная идея: предоставить набор общих внешних интерфейсов (высокоуровневый API) для подсистем."

основной код

Этот режим слишком простой, поэтому сразу переходите к коду~

/**
 * 定义一个顶层接口
 */
public interface Computer {

    void open();
}

public class Cpu implements Computer{
    @Override
    public void open() {
        System.out.println("Cpu Open.");
    }
}

public class Ram implements Computer {
    @Override
    public void open() {
        System.out.println("Ram Open.");
    }
}

public class Ssd implements Computer {
    @Override
    public void open() {
        System.out.println("SSD Open.");
    }
}

"Появление"

public class FacadeComputer {

    private Cpu cpu;
    private Ram ram;
    private Ssd ssd;

    public FacadeComputer() {
        this.cpu = new Cpu();
        this.ram = new Ram();
        this.ssd = new Ssd();
    }

    /** Cpu On **/
    public void onCpu() {
        this.cpu.open();
    }

    /** Ram On **/
    public void onRam() {
        this.ram.open();
    }

    /** Ssd On **/
    public void onSsd() {
        this.ssd.open();
    }

    /** All On **/
    public void allOn() {
        this.cpu.open();
        this.ram.open();
        this.ssd.open();
    }
}

"сравнение звонков"

/****
 * 推荐阅读顺序:
 * @see Computer
 * @see Cpu | Ram | Ssd
 * @see FacadeComputer
 */
public static void main(String[] args) {
    // 不使用外观模式
    Computer cpu = new Cpu();
    Computer ram = new Ram();
    Computer ssd = new Ssd();
    cpu.open();
    ram.open();
    ssd.open();

    CodeUtils.spilt();

    // 使用外观模式
    FacadeComputer facadeComputer = new FacadeComputer();
    facadeComputer.allOn();
}

какие сценарии применяются

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

Код / практическое применение в жизни

Лучшее воплощение модели внешнего вида в жизнь – это фонд.Суть фонда – это фактически профессиональная команда по сбору средств для покупки акций.Много процедур и мер предосторожности при покупке акций, но теперь мы можем легко делать ставки на средства.Это является одним из проявлений режима видимости.

Связанные ссылки на код

Адрес GitHub

  • С учетом кейсов в двух классических книгах "HeadFirst" и "GOF"
  • Предоставляет дружественное руководство по чтению