软件设计 适配器模式 Adapter Pattern

适配器模式 Adapter Pattern

 

在生活中,我们经常遇到这样的一个问题:轻薄笔记本通常只有 type-c 或者 usb-a 接口,没有网口。但日常使用中是往往需要连接网口上网的,这时想到的第一个解决方案,就是去买一个转接头或者扩展坞。它们可以将 type-c 或者 usb-a 转换为其他类型的接口供我们使用,实际上这就是一种适配器模式

我们常用的充电头,为什么叫电源适配器呢?

传统的供电是 220V 交流电,但是手机可能只需要 5V 的电压进行充电,所以虽然现在有电,但是不能直接充。也不可能让电力公司专门为我们提供一个 5V 的直流电使用,这时电源适配器就开始发挥作用了。比如苹果的祖传 5V1A 充电头,实际上就是将 220V 交流电转换为 5V 的直流电进行传输。这样就相当于在 220V 交流电和手机之间,做了一个适配器的角色

 

类适配器模式 (继承关系)

1、定义电脑

/**
* 电脑
* 想上网,需要插网线
*/
public class Computer {
   /**
    * 电脑需要连接上转换器才可以上网
    *
    * @param adapter 转接器
    */
   public void connect(NetToUsb adapter) {
       // 上网的具体实现,找一个转接头
       adapter.connectNetLine();
  }
}

2、定义网线

/**
* 网线
*/
public class NetLine {
   /**
    * 上网
    */
   public void online(){
       System.out.println("连接网线上网");
  }
}

3、定义 usb 网口 转接器

/**
* 转接器(接口)
*/
public interface NetToUsb {
   /**
    * 处理请求,usb -> 网线
    */
   void connectNetLine();
}

4、定义类适配器

/**
* 类适配器
*/
public class ClassAdapter extends NetLine implements NetToUsb {
   @Override
   public void connectNetLine() {
       // 可以上网了
       super.online();
  }
}
5、使用适配器连接网线上网

// 电脑
Computer computer = new Computer();
// 转接器已经插上网线
ClassAdapter adapter = new ClassAdapter();
// 电脑连接转接器,成功上网
computer.connect(adapter);

这种实现方式需要占用一个继承位。如果此时 NetToUsb 不是接口而是抽象类的话,由于 Java 不支持多继承,就无法实现了。同时根据合成复用原则,应该更多的通过合成的方式去实现功能。

 

对象适配器模式(关联关系)

用的比较多的一种模式:对象适配器模式

1、定义电脑

/**
* 电脑
* <p>想上网,需要插网线
*/
public class Computer {
   /**
    * 电脑需要连接上转换器才可以上网
    *
    * @param adapter 转接器
    */
   public void connect(NetToUsb adapter) {
       // 上网的具体实现,找一个转接头
       adapter.connectNetLine();
  }
}

2、定义网线

/**
* 网线
*/
public class NetLine {
   /**
    * 上网
    */
   public void online(){
       System.out.println("连接网线上网");
  }
}

3、定义 usb 转网口转接器

/**
* 转接器
*/
public interface NetToUsb {
   /**
    * 处理请求,usb -> 网线
    */
   void connectNetLine();
}

4、定义对象适配器

/**
* 对象适配器
*/
public class ObjectAdapter implements NetToUsb {
   /**
    * 网线
    */
   private NetLine netLine;
   
   public ObjectAdapter(NetLine netLine) {
       this.netLine = netLine;
  }
   
   @Override
   public void connectNetLine() {
       // 可以上网了
       netLine.online();
  }
   
}
5、使用适配器连接网线上网

/**
* 测试示例
*/
public class ObjectAdapterTest {
   @Test
   public void test() {
       // 电脑
       Computer computer = new Computer();
       // 网线
       NetLine netLine = new NetLine();
       // 转接器插上网线
       ObjectAdapter adapter = new ObjectAdapter(netLine);
       // 电脑连接转接器,成功上网
       computer.connect(adapter);
  }
}

这样的方式不会占用继承位,且满足合成复用原则,耦合度更低,也更加灵活,推荐使用

 

优缺点:

优点

1、可以让任何两个没有关联的类一起运行。

2、提高了类的复用。

3、增加了类的透明度。

4、灵活性好。

缺点

1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。

2、由于 Java 至多继承一个类,所以至多只能适配一个类,而且目标类必须是抽象类。

 

注意:

适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。

posted @ 2022-12-15 00:13  kuaiquxie  阅读(121)  评论(0编辑  收藏  举报