Adapter Design Pattern
适配器模式(Adapter Design Pattern)是一种结构型设计模式。意图把一个结构的既有接口转换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法一起工作的两个结构能够一起工作。
对于这个模式,有一个经常被拿来解释它的例子,就是 USB 转接头充当适配器,把两种不兼容的接口,通过转接变得可以一起工作。
UML Diagram
- Client 为主调方,依赖 Target 接口;
- Target 表示目标接口定义;
- Adaptee 为一组不兼容 Target 接口定义的接口(被适配的结构);
- Adaptor 将 Adaptee 转化成一组符合 Target 接口定义的接口;
适配器模式也可以称为 Wrapper 模式,通过构建(内嵌一个接口不匹配的 Adaptee)Wrapper 结构来对 Adaptee 进行能力转换以实现 Target 接口。
由于 Client 的业务逻辑依赖的是抽象(Target 接口)而非具体的结构类型,原本无法与 Client 对接的 Adaptee 经过 Adapter 包装也可以与 Client 对接了。
Example
Question:
mac 电脑具备接入 Lightning 插头的能力。
windows 电脑具备接入 USB 插头的能力。
client 希望将 Lightning 插头接入两台电脑,应如何处理?
Code:
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
51
52
53
54
55
|
package main
import "fmt"
// 主调方依赖的目标接口
type computer interface {
insertIntoLightningPort()
}
// 已实现目标接口
type mac struct{}
func (m *mac) insertIntoLightningPort() {
fmt.Println("Lightning connector is plugged into mac machine.")
}
// 未实现目标接口,待适配
type windows struct{}
func (w *windows) insertIntoUSBPort() {
fmt.Println("USB connector is plugged into windows machine.")
}
// 适配器
type windowsAdapter struct {
windowMachine *windows
}
// 适配器通过能力转换(适配),实现目标接口
func (w *windowsAdapter) insertIntoLightningPort() {
fmt.Println("Adapter converts Lightning signal to USB......")
w.windowMachine.insertIntoUSBPort()
}
// 主调方
type client struct{}
// 主调方的业务逻辑依赖的是目标接口,而非具体的实现
func (c *client) insertLightningConnectorIntoComputer(com computer) {
com.insertIntoLightningPort()
}
func main() {
client := &client{}
mac := &mac{}
client.insertLightningConnectorIntoComputer(mac)
windowsMachine := &windows{}
windowsMachineAdapter := &windowsAdapter{
windowMachine: windowsMachine,
}
client.insertLightningConnectorIntoComputer(windowsMachineAdapter)
}
|
Output:
Lightning connector is plugged into mac machine.
Adapter converts Lightning signal to USB......
USB connector is plugged into windows machine.
Application Scenarios
- 封装有缺陷的接口设计
- 统一多个类的接口设计
- 替换依赖的外部系统
- 兼容老版本接口
- 适配不同格式的数据
References
https://time.geekbang.org/column/article/205912
https://golangbyexample.com/adapter-design-pattern-go/