0%

适配器模式

背景

适配器模式目的是为了让接口不兼容的对象能够相互合作,例如一个流数据处理的第三方库,它目前只能处理XML格式输入的数据,但是你自己从生产环境获取到数据流是JSON格式的,因此你无法直接使用这个第三方库,因为它所需的输入数据与你的程序不兼容。

你可以修改这个第三方库来支持JSON,但是这可能需要修改其他依赖这个第三库的现有代码,甚至你可能根本就没有这个第三方库的源代码。

这时,你可以创建一个适配器,它用于将JSON格式数据转换为XML格式的数据,并调用第三方库进行数据处理,你的代码之后就与这个适配器进行交互。

适配器模式简介

  • 适配器实现与其中一个现有对象兼容的接口
  • 其他对象可以使用该接口安全得调用适配器方法
  • 适配器方法被调用后再调用其内部对象的接口
有时你甚至可以创建一个双向适配器来实现双向转换调用

代码示例

经典的方钉圆孔问题:

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
class RoundReg {
private:
int _radius;

public:
RoundReg(int radius): _radius(radius) {}
virtual int getRadius() {
return _radius
}
};

class RoundHole {
private:
int _radius;

public:
RoundHole(int radius): _radius(radius) {}
virtual int getRadius() {
return _radius
}
bool fits(RoundReg &roundReg) {
return _radius == roundReg.getRadius()
}
};

class SquareReg {
private:
int _edge;

private:
SquareReg(int edge): _edge(edge) {}
int getEdge() {
return _edge;
}
}

class SquarePegAdapter: RoundReg {
private:
SquareReg _squareReg;

public:
SquarePegAdapter(const SquareReg& peg): _squareReg(peg) {}
int getRadius() override {
return _squareReg.getEdge() * sqrt(2) / 2
}
};

SquarePegAdapter内部封装了SquareReg,RoundHole不能直接和SquareReg交互,而和SquarePegAdapter进行交互。

虽然SquarePegAdapter继承自RoundReg,但是这里继承的目的只是为了获取和RoundReg相同的接口而已,SquareRegAdapter相当于为SquarePeg增加了新的接口