《一天一模式》— 适配器模式

1、适配器模式的概念

将一个接口转换成客户但愿的另外一个接口,使接口不兼容的那些类能够一块儿工做,其别名为包装器(Wrapper)。 java

2、何时使用适配器模式

通常的通俗例子是:咱们生活用电是220V,给手机充电通常是5V,直接用220V充电是不行的,因此须要一个变压器(适配器),把220V变成5V。编程

用程序设计来解释,项目初始阶段的需求是:app

  • 有一个方法,输入参数是狮子对象;
  • 打印出狮子的一些特征;

程序上线后一段时间,需求有变动,须要让这个方法也接收老虎对象,打印老虎的特征,在不改变程序的前提下改如何作?测试

答案就是使用适配器模式来解决这个问题。this

 我的理解是,适配器模式的最大使用场景有两个:spa

  • 在项目需求有变动的状况下,不修改原来的代码,加入适配器来解决需求变动
  • 在没有办法修改源码的状况下,加入适配器来解决问题

3、如何使用适配器模式

3.1 实现方式

用一个实际的项目场景来举例:设计

  • 有一种设备(TBox),在汽车出厂前安装到了汽车内部,它能够根据协议,向服务端上报汽车点火、控制和熄火的事件;
  • 服务端有一个方法叫handler,接收这个协议;

程序上线后,通过一段时间,有新的需求须要实现:code

  • 一种新设备(OBD),有一些汽没有安装TBox,这种状况下,能够购买OBD设备安装到汽车上;
  • OBD能够向服务端上报点火和熄火事件,可是不能上报远程控制的事件;
  • 在不修改服务端handler方法的状况下,让服务端适配OBD协议;

这种状况下就可使用适配器模式了,下面是类图和代码:server

实现代码:对象

// TBox的协议接口。
public interface TBoxProtocol {

    // 点火
    void engineOn();

    // 熄火
    void engineOff();

    // 远程控制
    void control();

}

// TBox对象,实现了TBox协议
public class TBox implements TBoxProtocol {

    // 点火
    public void engineOn() {
        System.out.println("TBox协议:点火");
    }

    // 熄火
    public void engineOff() {
        System.out.println("TBox协议:熄火");
    }

    // 远程控制
    public void control() {
        System.out.println("TBox协议:远程控制");
    }

}

// 模拟一个服务端,接收TBox协议作某些业务
public class Server {

    // 先点火、在进行远程控制、在熄火
    public void handler(TBoxProtocol tBoxProtocol) {
        tBoxProtocol.engineOn();
        tBoxProtocol.control();
        tBoxProtocol.engineOff();
    }

}
// OBD协议
public interface OBDProtocol {

    // 点火
    void engineOn();

    // 熄火
    void engineOff();

}

// OBD对象,实现了OBD协议
public class OBD implements OBDProtocol {

    // 点火
    public void engineOn() {
        System.out.println("OBD协议:点火");
    }

    // 熄火
    public void engineOff() {
        System.out.println("OBD协议:熄火");
    }
}
// TBox适配器,将OBD适配成TBox
public class TBoxAdapter implements TBoxProtocol {

    // 注入一个OBD协议
    private OBDProtocol obdProtocol;

    public TBoxAdapter(OBDProtocol obdProtocol) {
        this.obdProtocol = obdProtocol;
    }

    // 在点火,熄火,远程控制时,调用OBD协议在这几个场景下的业务方法
    public void engineOn() {
        obdProtocol.engineOn();
    }

    public void engineOff() {
        obdProtocol.engineOff();
    }

    public void control() {
        // 若是OBD不支持某方法,能够作其余处理
        System.out.println("OBD不支持远程控制。");
    }
}
public class Client {

    public static void main(String[] args) {
        // 建立一个服务端
        Server server = new Server();

        // 建立一个TBox协议,而后发送给服务端
        TBoxProtocol tBoxProtocol = new TBox();
        server.handler(tBoxProtocol);

        System.out.println();

        // TBox
        TBoxAdapter tBoxAdapter = new TBoxAdapter(new OBD());
        server.handler(tBoxAdapter);
    }

}

// 输入
TBox协议:点火
TBox协议:远程控制
TBox协议:熄火

OBD协议:点火
OBD不支持远程控制。
OBD协议:熄火

3.2 适配器模式的好处

适配器的好处以下:

  • 开闭原则:应对需求变动,在不修改现有代码的状况下,打到预期效果,符合开闭原则;
  • 简单透明:客户端能够调用同一接口来完成业务,可就是说对客户端无影响,耦合低;
  • 扩展性强:在实现适配器功能的时候,能够在调用过程当中作其余业务,增强了扩展性,更加灵活;

3.3 使用适配器模式须要注意的地方

过多的使用适配器,会让系统的总体设计变得零乱。

因此,须要养成良好的设计习惯,对文档和图例及时进行更新,编写的简单易懂,要与现有代码一致。

4、总结

适配器模式的作法,从程序的角度去理解的话,能够按照以下步骤:

  • 建立一个适配器,实现或者继承一个目标(若是目标没有接口,则须要继承目标对象,强烈建议基于接口编程,这样能够省下类宝贵的继承机会);
  • 在适配器中注入被适配的类,以参数方式传递给适配器;
  • 适配器实现或重写(对应实现接口或继承类)目标类方法,在方法内调用被适配的类的方法,实现业务;

从业务角度的话,和在第二小节描述使用场景时同样:

  • 在需求变动时候,符合开闭原则,不修改原来的代码,加入适配器实现接口适配,减小测试范围
  • 在没有办法修改源码的状况下,加入适配器,完成业务

以上就是我对适配器模式的一些理解,有不足之处请你们指出,谢谢。

相关文章
相关标签/搜索