目录
- 一、适用场景
-
- [1.1 现实场景举例](#1.1 现实场景举例)
- [1.2 修改](#1.2 修改)
- 二、使用环境
- 三、适配器模式详解
- 四、适配器模式分类
- 五、应该用哪种适配器
- 六、实现步骤
- 七、代码实现
-
- [7.1 确定目标接口](#7.1 确定目标接口)
- [7.2 确定被适配者](#7.2 确定被适配者)
- [7.3 创建适配器](#7.3 创建适配器)
-
- [7.3.1 类适配器](#7.3.1 类适配器)
- [7.3.2 对象适配器](#7.3.2 对象适配器)
一、适用场景
1.1 现实场景举例
- 已经存在的接口如下
cpp
class ITarget
{
public:
void run();
};
- 如果要再加一个
fly()
方法,还要求不能违反开放封闭
原则要如何处理
1.2 修改
- 在
ITarget
接口中添加void fly();
方法 - 违反了
对修改进行封闭
的原则,这样做了之后,以前实现该接口的类都要实现该方法。 - 此时,就要用到适配器模式
二、使用环境
- 想使用一个已经存在的类,但他的接口不符合需求
- 将一个类的接口转换成客户希望的另外一个接口,使得原来由于接口不兼容而不能在一起工作的那些类可以一起工作。
三、适配器模式详解
- 适配器模式有以下四种角色
- 目标(target):定义客户端使用的与特定领域相关的接口
- 被适配者(adaptee):定义了一个已经存在的接口,这个接口需要匹配。
- 适配者(adapter):对Adaptee的接口与target的接口进行适配
- 客户端(client):与符合target接口的对象协同
四、适配器模式分类
- 类的适配器模式(采用
继承
实现)
- Target:就是最终的包括
run()
和fly()
的接口 - Adaptee: 等待着被转换(完成
fly()
的类) - Adapter: 要被转换的结果对象,只要继承Adaptee接口并实现Target即可
- Target:就是最终的包括
- 对象适配器(采用
对象组合
方式实现,推荐,也满足合成复用原则)
- 与
类的适配器
结构基本相同 - 差异在于Adapter和Adaptee的关系上
- 类的适配器模式采用继承关系
- 对象适配器采用关联关系,关联关系的箭头端的类(Adaptee)会有一个实例进入箭头末端的类(Adapter)中。
五、应该用哪种适配器
- 类适配器采用"多继承"的实现方式,带来了不良的高耦合
- 对象适配器采用"对象组合"的方式,更符合松耦合精神
- 类适配器无法面对多个被适配对象
- 推荐使用
对象适配器
六、实现步骤
两种适配器的步骤相同
- 确定目标接口
- 确定被适配者
- 创建适配器(继承自被适配者/拥有被适配者的对象,实现目标接口)
七、代码实现
7.1 确定目标接口
cpp
class ITarget
{
public:
virtual void run() = 0;
virtual void fly() = 0;
};
7.2 确定被适配者
cpp
class Deer
{
public:
void run()
{
std::cout << "I can run." << std::endl;
}
};
7.3 创建适配器
7.3.1 类适配器
cpp
#include <iostream>
class ITarget
{
public:
virtual void run() = 0;
virtual void fly() = 0;
virtual ~ITarget() = default;
};
class Deer
{
public:
void run()
{
std::cout << "I can run." << std::endl;
}
};
//继承原有的Deer,并实现ITarget
class classAdapter : public Deer, public ITarget
{
public:
void fly() override
{
std::cout << "I can fly" << std::endl;
}
//显式的告诉编译器使用Deer中的run来实现ITarget中的run
void run() override
{
Deer::run();
}
};
int main()
{
ITarget* target = new classAdapter();
target->fly();
target->run();
delete(target);
return 0;
}
7.3.2 对象适配器
cpp
#include <iostream>
class ITarget
{
public:
virtual void run() = 0;
virtual void fly() = 0;
virtual ~ITarget() = default;
};
class Deer
{
public:
void run()
{
std::cout << "I can run." << std::endl;
}
};
//继承原有的Deer,并实现ITarget
class classAdapter: public ITarget
{
private:
Deer* m_deer; //有一个Deer的实例,在构造函数中被赋值
public:
classAdapter(Deer* deer)
{
m_deer = deer;
}
void fly() override
{
std::cout << "I can fly" << std::endl;
}
void run() override
{
m_deer->run();
}
};
int main()
{
Deer d;
ITarget* target = new classAdapter(&d);
target->fly();
target->run();
delete(target);
return 0;
}