Adapter Pattern(适配器模式)
适配器模式是作为两个不兼容的接口之间的桥梁,它结合了两个独立接口的功能。
举个例子,生活中无处不在的转换头其实就是一种适配器,例如读卡器,内存条插在读卡器上,再将读卡器插在笔记本插槽上,这样笔记本就可以读取内存条了;再例如type-c孔到USB孔的转接头,macbook pro笔记本上的typec孔,我们经常要连键盘,而键盘是需要USB孔才可以插入的,这个时候就需要一个typec转USB的转接头,这就是一个典型的适配器。
适配器模式用于转换一种形态到另一种形态,使功能能够正常使用,达到适配的效果
五大要素
来看看适配器模式的五大要素:
- 模式名称:适配器模式
- 目的(What):将一个类的接口转化为客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作
- 解决的问题(Why):系统需要使用现有的类,而此类的接口不符合系统当前的需要,主要解决的是将一些现存的对象放到新的环境中,而新环境要求的接口是现对象不能满足的。
- 解决方案(How):采用一个新的适配器对象,实现的是新的接口,但是包含的是现有的类,在实现新接口时,实际调用的是现有的类的接口
- 解决效果:
- 优点:
- 可以让两个无关的类一起运行
- 提高了类的复用
- 增加了类的透明度
- 灵活性好
- 缺点:
- 过多的使用适配器,会让系统非常凌乱,不易整体把握;如果不是必要,可以不使用适配器,而是直接对系统进行重构
- 优点:
Go实现适配器工厂模式
场景
现在只有Type-C接口,当前有一个键盘,但它使用的是USB接口,要求实现一个适配器转接头,使得键盘也可以插上Type-C接口成功使用。
adapter.go
:
package adapter
// TypeC接口
type TypeC interface {
UseTypeC() string
}
// USB接口
type USB interface {
UseUSB() string
}
func NewUSB() USB {
return &keyboard{}
}
type keyboard struct{}
// keyboard实现了USB接口
func (a *keyboard) UseUSB() string {
return "I use USB interface"
}
//NewAdapter 是适配器的工厂函数
func NewAdapter(keyboard USB) TypeC {
return &adapter{
USB: keyboard,
}
}
//Adapter是适配器对象,其中包含一个USB成员
type adapter struct {
USB
}
//UseTypeC实现了Type-C接口
func (a *adapter) UseTypeC() string {
return a.UseUSB() + ", but now I use Type-C interface"
}
adapter_test.go
:
package adapter
import "testing"
func TestAdapter(t *testing.T) {
usb := NewUSB()
adapter := NewAdapter(usb)
t.Log(usb.UseUSB())
t.Log(adapter.UseTypeC())
}
执行测试结果:
--- PASS: TestAdapter (0.00s)
adapter_test.go:14: I use USB interface
adapter_test.go:15: I use USB interface, but now I use Type-C interface
PASS