【结构型】适配器模式

Posted by Liao on 2020-04-02

一、定义

将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的类能够一起工作。

二、结构

Adapter->Adaptee是组合的关系(is a)

三、例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// 目标接口(新接口)
class ITarget {
public:
//The = 0 makes the function pure virtual, rendering the class an abstract class.
virtual void process()=0;

};

//遗留接口(老接口)
class IAdaptee {
public:
virtual void foo(int data)=0;
virtual int bar()=0;
};


//遗留类型
class OldClass: public IAdaptee {
//...
};

//种类一:对象适配器(通过组合对象来实现)
class Adapter: public ITarget { //继承
protected:
IAdaptee* pAdaptee; // 组合(比较灵活,可以指向不同的对象,更符合松耦合的原则)
public:
Adapter(IAdaptee* pAdaptee) { //构造器
this->pAdaptee = pAdaptee;
}
virtual void process() {
int data = pAdaptee->bar();
pAdaptee->foo(data);
}
};


//种类二:类适配器
class Adapter: public ITarget, protected IAdaptee { //多继承(不灵活,定死了继承的类,不推荐使用)

};


int main() {
//1、旧的类,2、放到适配器里,3、可以当成新接口使用
IAdaptee* pAdaptee = new OldClass(); // 1

ITarget* pTarget = new Adapter(pAdaptee); // 2
pTarget->process(); // 3
}

例子一、c++的stl中,deque是queue和stack的适配器。
例子二:有一个220v电压,需要适配器转成5V电压才能给手机充电。
类适配器(不推荐使用)

被适配器类:Voltage220V 适配类:Voltage5V

通过适配器类VoltageAdapter继承Voltage220V(拿到220V电压),并且实现了Voltage5V的接口(并转乘5V)

手机类依赖Voltage5V,实质上是依赖VoltageAdapter

对象适配器

由于Java单继承原因

对类适配器模式进行改进,不需要继承原先的类,而是直接持有被适配对象

通过合成复用原则,由继承关系转变为聚合关系

1
2
3
public class VoltageAapter implements Voltage{
private Voltage220 voltage220;
}
接口适配器

如果不需要试下全部接口中的方法,可先设计一个抽象类实现接口,并为该接口的每个方法提供默认空方法,那么该抽象类的子类就能有选择性地覆盖父类某些方法来实现需求。