设计模式——适配器模式(Adapter)

适配器模式(Adapter Pattern)是一种结构型设计模式,主要用于将一个类的接口转换成客户端所期望的另一种接口,从而使得原本因接口不兼容而无法一起工作的类能够协同工作。

适配器模式主要解决两类问题:

  1. 类的接口不兼容问题:客户端期望的接口与现有类的接口不一致,导致无法直接使用。
  2. 类的复用问题:现有类需要与其他不相关或不可预见的类协同工作,但由于接口不兼容而无法直接组合使用。

适配器模式主要分为两种类型:

  1. 类适配器模式:通过多重继承将适配器类同时继承自现有类和目标接口,以实现接口转换。在Java等不支持多重继承的语言中,通常通过接口和组合关系来实现类似的效果。
  2. 对象适配器模式:将现有类的对象作为适配器类的一个属性,通过适配器类来调用现有类的方法,从而实现接口转换。这种方式更符合"组合优于继承"的原则,因此在实践中更为常用。

适配器模式的主要优点包括:

  1. 提高了系统的灵活性和可扩展性:通过适配器模式,可以使得原本不兼容的类能够协同工作,提高了系统的灵活性。同时,由于适配器模式的实现相对独立,因此可以根据需要添加新的适配器类,从而扩展系统的功能。
  2. 复用了现有代码:适配器模式充分利用了现有类的方法和数据,无需修改现有类的代码即可实现接口转换,从而降低了开发成本。
  3. 解耦了客户端和现有类:通过适配器模式,客户端只需与适配器类进行交互,而无需直接调用现有类的方法,从而降低了客户端与现有类之间的耦合度。

适配器模式的一个典型应用场景是笔记本电脑使用三相电流而插座为二相供电的情况。在这种情况下,可以通过使用一个适配器将二相插座转换为笔记本电脑所需的三相接口,从而使得笔记本电脑能够正常充电。在这个例子中,适配器类充当了现有类(二相插座)和目标接口(三相接口)之间的桥梁,实现了接口转换和复用现有代码的目的。

以下是一个简单的Java代码示例,演示了对象适配器模式(Object Adapter Pattern)的实现。

首先,我们定义一个目标接口(Target),这是客户端所期望的接口:

java 复制代码
public interface Target {
    void request();
}

然后,我们有一个现有的类(Adaptee),它的接口与Target不兼容:

java 复制代码
public class Adaptee {
    public void specificRequest() {
        System.out.println("Called specificRequest()");
    }
}

现在,我们创建一个适配器类(Adapter),它实现了Target接口,并且持有一个Adaptee类型的对象,以便在request方法中调用AdapteespecificRequest方法:

java 复制代码
public class Adapter implements Target {
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

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

最后,我们有一个客户端类(Client),它使用Target接口来请求服务:

java 复制代码
public class Client {
    public static void main(String[] args) {
        // 创建一个Adaptee对象
        Adaptee adaptee = new Adaptee();

        // 创建一个Adapter对象,并将Adaptee对象传递给Adapter
        Target target = new Adapter(adaptee);

        // 使用Target接口请求服务
        target.request();
    }
}

当你运行Client类的main方法时,会输出:

复制代码
Called specificRequest()

这表明客户端通过适配器成功调用了AdapteespecificRequest方法,尽管Adaptee的接口与客户端所期望的Target接口不同。这就是适配器模式的核心思想:将一个类的接口转换成客户端所期望的另一种接口,使得原本不兼容的类能够协同工作。

相关推荐
一木 之林4 小时前
第 8 节 C++ 设计模式在 AI 推理 SDK 和 Agent 工具运行时中如何落地
c++·人工智能·设计模式
Zane19948 小时前
MVC 三层架构被打上反模式标签?一次账户扣款需求,讲清楚贫血模型和充血模型该怎么选
设计模式
geovindu1 天前
rust:Builder Pattern
开发语言·设计模式·rust·建造者模式
小王师傅661 天前
【设计模式】装饰模式(三):从装饰模式看 Java 与面向对象设计(原理篇)
设计模式
Zane19941 天前
从一次支付渠道扩展需求,看懂"多用组合少用继承"到底在说什么
设计模式
geovindu1 天前
CSharp:Condition Variable Pattern
后端·设计模式·c#·.net·.netcore·条件变量模式·同步型模式
geovindu1 天前
sql: Data Modeling Patterns using mysql
sql·mysql·设计模式·数据库开发
sarasuki2 天前
失败重试:Agent 中指数退避的正确姿势
人工智能·设计模式·agent
Zane19942 天前
为什么你写的 Java 代码"看着面向对象、实际是面向过程"?
设计模式
geovindu2 天前
sql: Data Modeling Patterns
数据库·sql·设计模式·sqlserver