【设计模式】适配器模式

[1. 模式说明](#1. 模式说明)

[2. 模式原理](#2. 模式原理)

[2.1 类的适配器模式](#2.1 类的适配器模式)

[2.2 对象的适配器模式](#2.2 对象的适配器模式)

两种方式的优缺点


1. 模式说明

适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将一个接口转换成客户端所期望的另一种接口。适配器模式的核心思想是通过创建一个中间层(适配器),使得原本由于接口不兼容而无法一起工作的类可以协同工作。

适配器模式有两种主要形式:

  1. 类适配器:通过继承来实现适配。

  2. 对象适配器:通过组合来实现适配,更常用且更灵活。

2. 模式原理

2.1 类的适配器模式

类的适配器模式是把适配的类的API转换成为目标类的API。

2.1.1 UML类图 & 组成

在上图中可以看出:

  • 冲突:Target期待调用Request方法,而Adaptee并没有(这就是所谓的不兼容了)。
  • 解决方案:为使Target能够使用Adaptee类里的SpecificRequest方法,故提供一个中间环节Adapter类**(继承Adaptee & 实现Target接口)**,把Adaptee的API与Target的API衔接起来(适配)。

Adapter与Adaptee是继承关系,这决定了这个适配器模式是类的

2.1.3 实例讲解

cpp 复制代码
// 目标接口   (原接口,不想修改)
class Target {
public:
    virtual void request() = 0;
};


// 被适配类   (新接口)
class Adaptee {
public:
    void specificRequest() {
        std::cout << "Adaptee specific request" << std::endl;
    }
};




新接口的名字specificRequest不一样了,不能被原代码直接调用。搞一个类适配器包裹封装(适配)出原来的接口:->request()


// 类适配器
class Adapter : public Target, public Adaptee { // 继承Target和Adaptee
public:
    void request() override {
        specificRequest(); // 调用Adaptee的方法
    }
};


通过适配器,可以用原来的调用代码target->request() 调用新功能:

int main() {
    Target* target = new Adapter();
    target->request(); // 输出: Adaptee specific request

    delete target;
    return 0;
}

main函数中,我们创建了一个Adapter对象,并通过Target指针来调用其request方法。由于Adapter实现了Target接口,并且在其request方法中调用了AdapteespecificRequest方法,所以客户端代码可以透明地使用Target接口,而不需要关心底层的Adaptee实现。

2.2 对象的适配器模式

与类的适配器模式相同,对象的适配器模式也是把适配的类的API转换成为目标类的API。

与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类。

2.2.1 UML类图

在上图中可以看出:

• 冲突:Target期待调用Request方法,而Adaptee并没有(这就是所谓的不兼容了)。

• 解决方案:为使Target能够使用Adaptee类里的SpecificRequest方法,故提供一个中间环节Adapter类(包装了一个Adaptee的实例),把Adaptee的API与Target的API衔接起来(适配)。

Adapter与Adaptee是委派关系,这决定了适配器模式是对象的。

2.2.2 实例讲解

cpp 复制代码
// 目标接口  (原接口,不想改)
class Target {
public:
    virtual void request() = 0;
};


// 被适配类  (新接口)
class Adaptee {
public:
    void specificRequest() {
        std::cout << "Adaptee specific request" << std::endl;
    }
};


创建适配器(但是不继承Target和Adaptee,而是在其中创建新接口的对象)


// 适配器类(对象适配器)
class Adapter : public Target {
public:
    Adapter(Adaptee* adaptee) : m_adaptee(adaptee) {}

    void request() override {
        m_adaptee->specificRequest();
    }

private:
    Adaptee* m_adaptee;
};


原代码中创建适配器,就可以使用原来的接口调用新功能 target->request()

int main() {
    Adaptee* adaptee = new Adaptee();
    Target* target = new Adapter(adaptee);
    target->request();
    
    delete target;
    delete adaptee;
    return 0;
}

两种方式的优缺点

3.2 类的适配器模式

优点

• 使用方便,代码简化

仅仅引入一个对象,并不需要额外的字段来引用Adaptee实例

缺点

• 高耦合,灵活性低

使用对象继承的方式,是静态的定义方式

3.3 对象的适配器模式

优点

• 灵活性高、低耦合

采用 "对象组合"的方式,是动态组合方式

缺点

• 使用复杂

需要引入对象实例

特别是需要重新定义Adaptee行为时需要重新定义Adaptee的子类,并将适配器组合适配

参考:https://www.jianshu.com/p/9d0575311214

相关推荐
缘友一世14 小时前
JAVA代理模式和适配器模式
java·代理模式·适配器模式
抓哇FullStack-Junior2 天前
设计模式——适配器模式
java·设计模式·适配器模式
ThetaarSofVenice2 天前
带着国标充电器出国怎么办? 适配器模式(Adapter Pattern)
java·适配器模式
窗外的寒风2 天前
java工作流模式、背包模式、适配器工厂模式整合架构,让服务任务编排更便捷
架构·适配器模式
越甲八千3 天前
重温设计模式--代理、中介者、适配器模式的异同
设计模式·适配器模式
越甲八千7 天前
重拾设计模式-外观模式和适配器模式的异同
设计模式·适配器模式·外观模式
越甲八千7 天前
重拾设计模式--适配器模式
设计模式·适配器模式
诸葛悠闲10 天前
设计模式——适配器模式
设计模式·适配器模式
西岭千秋雪_10 天前
设计模式の建造者&适配器&桥接模式
java·设计模式·建造者模式·桥接模式·适配器模式