概念
适配器模式:将一个类的接口转换为用户希望的另一个接口, Adapter模式是的原本由于接口不兼容而不能一起工作的那些类可以一起工作。
这种类型的设计模式属于结构型模式。
UML图
<img src="doc/adapterpattern.jpg"/>
具体实现:
简单来说是: 定一个一个目标接口, 一个需要被适配的接口, 适配器结构体实现这个目标接口, 并包含被适配接口。 被适配结构体实现被适配接口, 将结构体实例传递给适配器, 让适配器可以通过实现的目标接口方法来调用。 用户直接使用适配器调用目标接口调用到被适配的接口。
- 定义一个一个目标接口, 目标接口包含需要的方法接口。
- 定义一个需要被适配的结构体的接口, 这个接口方法是需要具体调用的方法。
- 定义一个适配器结构体, 适配器结构体包含被适配的结构体的接口, 实现了目标接口, 目标接口调用被适配接口的方法, 同时定义一个实例化方法, 参数是被适配结构体接口, 将接口返回出去。
- 定义一个实现了需要被适配的接口的结构体, 将结构体实例传递给 适配器。
适配器模式的场景和优缺点
使用场景
希望使用一个已经存在的接口, 但是他的具体方法和要求不相同的时候。这个时候可以加一个适配器。将适配器适配到现存的接口当中。
比如在需要对早期的代码复用一些功能的时候有价值。
优点
- 可以让任何两个没有关联的类一起运行
- 提高了类的复用
- 增加了类的透明度
- 灵活性好
缺点
- 过多地使用适配器,会让系统非常零乱,不易整体进行把握
代码实现
package main
import (
"fmt"
)
// 用户希望使用的目标接口
type Target interface {
Request() string
}
// ***********适配器,是将转换Adaptee为Target接口的适配器, 实现了Target接口***********
type adapter struct {
Adaptee
}
// NewAdapter 是Adapter的工厂函数
func NewAdapter(adaptee Adaptee) Target {
return &adapter{
Adaptee: adaptee,
}
}
// Request 实现Target接口
func (a *adapter) Request() string {
//调用的是目标的方法(转换成客户希望的另外一个接口)
return a.SpecificRequest()
}
// ************************************
// ********需要适配结构体的目标接口*********
type Adaptee interface {
SpecificRequest() string
}
// ************************************
// ********adapteeImpl需要适配的结构体, 实现了需要适配的目标接口 Adaptee************
type adapteeImpl struct{}
// NewAdaptee 是被适配接口的工厂函数
func NewAdaptee() Adaptee {
return &adapteeImpl{}
}
// SpecificRequest 是目标类的一个方法
func (*adapteeImpl) SpecificRequest() string {
return "adaptee method"
}
// ************************************
func main() {
adaptee := NewAdaptee()
target := NewAdapter(adaptee)
res := target.Request()
fmt.Printf("res:%s\n", res)
}