Bootstrap

设计模式之 适配器模式

适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将一个类的接口转换成客户端所期望的另一个接口。通过使用适配器模式,原本由于接口不兼容的类可以进行协作。简单来说,适配器模式就是将不兼容的接口连接起来,使得客户端能够与之交互而不需要修改原有代码。

在现实世界中,这就像是一个电压适配器,它将不同电压的插头转化为标准插座的电压和插头,以便设备能够正常使用。

一、适配器模式的结构

适配器模式的结构通常由以下几个部分组成:

  • Target(目标接口): 客户端依赖的接口。
  • Adapter(适配器): 通过继承或组合将 Adaptee 转换为 Target,使得客户端可以通过目标接口与适配者交互。
  • Adaptee(适配者): 需要适配的类,它的接口不能直接与客户端的接口兼容。

二、适配器模式的分类

适配器模式有两种常见的实现方式:

  1. 类适配器模式(Class Adapter Pattern):

    • 使用继承来实现适配。
    • 适配器类继承自适配者类,并实现目标接口。
    • 这种方式利用了类的继承关系,将适配者类的接口转换为目标接口。
  2. 对象适配器模式(Object Adapter Pattern):

    • 使用组合来实现适配。
    • 适配器类包含一个适配者对象,并通过该对象将适配者的接口转换为目标接口。
    • 这种方式通过对象组合的方式解决适配问题,相比类适配器模式,它更加灵活且避免了多重继承带来的复杂性。

三、适配器模式的示例

现有一台电脑只能读取SD卡,而要读取TF卡中的内容的话就需要使用到适配器模式。创建一个读卡器,将TF卡中的内容读取出来。

1. 示例一:类适配器模式
  • SD卡接口
    public interface SDCard {
        public void readSD();
    }
    
  • SD卡实现类
    public class SDCardImpl implements SDCard {
    
        @Override
        public void readSD() {
            System.out.println("正在读取SD卡信息");
        }
    }
  • 读卡器
    public class TFAdaptCD extends TFCardImpl implements SDCard {
        @Override
        public void readSD() {
            System.out.println("正在通过适配器读取");
            readTFCard();
        }
    }
  • TF卡接口
    public interface TFCard {
        public void readTFCard();
    }
    
  • TF卡实现类
    public class TFCardImpl implements TFCard {
    
        @Override
        public void readTFCard() {
            System.out.println("正在读取TF卡信息");
        }
    }
    
  • 电脑类
    public class Computer {
        public void readSD(SDCard cdCard){
            cdCard.readSD();
        }
    }
    
  • 测试类
    public class Client {
        public static void main(String[] args) {
            Computer computer = new Computer();
            computer.readSD(new SDCardImpl());
            computer.readSD(new TFAdaptCD());
        }
    }
  • 结果
2. 示例二:对象适配器模式

只需要更改适配器类

public class TFAdaptCD implements SDCard {
    TFCard tfCard = new TFCardImpl();
    @Override
    public void readSD() {
        System.out.println("正在通过适配器读取");
        tfCard.readTFCard();
    }
}

客户端类

public class Client {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.readSD(new SDCardImpl());
        computer.readSD(new TFAdaptCD(new TFCardImpl()));
    }
}

四、适配器模式的应用场景

适配器模式的使用场景通常包括以下几种情况:

  1. 需要使用一个已有的类,但它的接口和客户端需要的接口不兼容。

    当你想要复用一个已经存在的类,但它的接口与当前系统的接口不兼容时,适配器模式是一个有效的解决方案。
  2. 希望通过一个新接口来替代原本的接口,而不修改现有代码。

    适配器模式允许你在不改变原有代码的情况下,将现有的接口转化为你期望的接口。
  3. 希望让某个类与其他类协同工作,而它们的接口不兼容。

    适配器模式为不同的类提供了一个桥梁,使得它们能够协同工作。
  4. 希望对某个类的接口进行改造,但不想修改原类的实现。

    在这种情况下,适配器模式通过封装原有类的功能,提供一个新的接口,避免修改原始类的代码。
  5. 第三方库的接口不符合需求时。

    当你使用第三方库时,它的接口可能无法满足当前系统的需求。适配器模式可以帮助你对这些接口进行适配,使它们能够与现有系统兼容。

五、适配器模式的优缺点

优点:
  1. 解耦合: 客户端与适配者之间通过适配器进行交互,客户端不需要知道适配者的实现细节。客户端依赖于目标接口,而不是适配者的实现,增强了系统的灵活性。
  2. 复用性: 通过适配器模式,可以将多个不兼容的接口组合在一起进行复用,使系统具备更高的可复用性。
  3. 灵活性: 如果需要改变适配的类,适配器模式允许你不修改客户端代码,只需要更换适配器即可。
  4. 增强了系统的扩展性: 适配器模式可以帮助系统扩展新的功能,而不会影响现有的接口或系统。
缺点:
  1. 增加了额外的类: 适配器模式引入了额外的适配器类,这可能会使得系统的复杂性增加,尤其是当使用适配器类的数量较多时。
  2. 性能开销: 适配器类通常会做一些额外的转换工作,因此可能会带来一些性能开销,尤其是在高频次的调用场景中。
  3. 难以管理复杂的适配器: 当系统中需要适配的接口较多时,适配器的数量会增加,这可能会导致管理上的困难。

;