[设计模式] 适配器模式 + 外观模式

手机用户请横屏获取最佳阅读体验,REFERENCES中是本文参考的链接,如需要链接和更多资源,可以关注其他博客发布地址。

平台 地址
CSDN https://blog.csdn.net/sinat_28690417
简书 https://www.jianshu.com/u/3032cc862300
个人博客 https://yiyuery.github.io/NoteBooks/

适配器模式

适配器模式: 将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。

适配器有两种,一种是类适配器,另一种是对象适配器。

对象适配器

利用组合的方式将请求传送给被适配器

UML

[设计模式] 适配器模式 + 外观模式_设计模式

顾名思义,ProductV2API是新的API接口,ProductV1API为历史API接口,实现类HisAPIAdaptee为历史API的实现类,即被适配者。

代码

历史接口 & 实现


public interface ProductV1API {

    /**
     * V1 版本产品接口
     */
    void specificRequest();
}

public class HisAPIAdaptee implements ProductV1API {
    /**
     * V1 版本产品接口
     */
    @Override
    public void specificRequest() {
        System.out.println("Adaptee specificRequest");
    }
}

适配器实现新的接口,并传入历史接口的实现类(被适配者)

public class APIAdapter implements ProductV2API {

    private HisAPIAdaptee adaptee;

    public APIAdapter(HisAPIAdaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        adaptee.specificRequest();
    }


}

客户端调用

//客户端程序
public class Client {

    public static void main(String[] args) {
        //老接口使用
        HisAPIAdaptee hisAPIAdaptee = new HisAPIAdaptee();
        hisAPIAdaptee.specificRequest();

        //适配后新接口对外暴露使用
        new APIAdapter(hisAPIAdaptee).request();
    }
}

类适配器

利用多重继承实现,请求传送给被被适配者

APIAdapter 继承 ProductV1APIProductV2API的实现类,在适配器内部实现请求方法的转发。

但是Java中不允许这样做!

适配器和装饰者模式

各自特点

  • 适配器用来封装接口,解决接口版本迭代对客户端的兼容问题,适配器将一个接口转成另一个接口
  • 装饰者模式用来包裹对象,补充对象属性,被装饰者可以被装饰器替代使用,支持多层嵌套。
  • 装饰者模式不改变接口,但是加入责任

相似点

  • 都是通过包裹将操作委派给被装饰者和被适配者
  • 都会实现公共接口或是抽象基类

外观模式

外观模式:提供一个统一的接口,用来访问子系统的一群接口,外观定义了一个高层接口,让子系统更容易使用

UML

[设计模式] 适配器模式 + 外观模式_设计模式_02

//定义外观行为
public interface Facade {

    /**
     * 开启
     */
    void on();

    /**
     * 关闭
     */
    void off();
}

//实现外观行为并针对每个子系统进行统一的外观包装


//灯光控制
public class LightAPI implements Facade {
    /**
     * 开启
     */
    @Override
    public void on() {
        System.out.println("Light turned on!");
    }

    /**
     * 关闭
     */
    @Override
    public void off() {
        System.out.println("Light turned off!");
    }
}

//TV控制
public class TVAPI implements Facade {
    /**
     * 开启
     */
    @Override
    public void on() {
        System.out.println("TV turned on!");
    }

    /**
     * 关闭
     */
    @Override
    public void off() {
        System.out.println("TV turned off!");
    }
}

//全局外观控制
public class FacadeImpl implements Facade {

    LightAPI light = new LightAPI();
    TVAPI tv = new TVAPI();

    /**
     * 开启
     */
    @Override
    public void on() {
        light.on();
        tv.on();
    }

    /**
     * 关闭
     */
    @Override
    public void off() {
        light.off();
        tv.off();
    }
}

外观行为的接口定义可以换成其他具体类,非必要实现,外观模式的重点的是封装一批接口,对外提供一个高层接口。

设计原则:

  • 最少知识原则(只和亲密的朋友交谈)

总结

适配器模式

  • 当一个现有的类的使用,但是对应接口无法符合你的需要时,可以使用。
  • 可以改变接口以符合客户的期望
  • 适配器实现的复杂度和目标接口的大小和复杂度成正比
  • 类适配器需要使用多重继承,Java中无法使用
  • 适配器讲一个对象包装起来以改变其接口

外观模式:

  • 将客户从一个复杂子系统中解耦,提供一个高层次的应用接口。
  • 不同子系统接口的组合可以实现多个外观,视需求和接口复杂度而定。
  • 将一群对象包装起来以简化其接口

装饰者模式:

  • 将一个对象包装起来,以增加新的行为和责任

更多

扫码关注架构探险之道,回复文章标题,获取本文相关源码和资源链接

[设计模式] 适配器模式 + 外观模式_设计模式_03

知识星球(扫码加入获取历史源码和文章资源链接)

[设计模式] 适配器模式 + 外观模式_设计模式_04