将一个类的接口,转换成客户期望的另一个接口。适配器让原来接口不兼容的类可以合作无间。
Client:是包含当前程序业务逻辑的类
客户端代码只需通过与适配器交互即可,无需与具体的适配器耦合。因此,你可以向程序中添加新类型的适配器而无需修改已有代码。这在服务类的接口被更改或替换时很有用:你无需修改客户端代码就可以创建新的适配器类。
Client Interface:描述了其他类与客户端代码合作时必须遵循的协议
Service:有一些功能类(通常来自第三方或遗留系统)。客户端与其接口不兼容,因此无法直接调用其功能。
Adapter:是一个可以同时与客户端和服务端交互的类:它是实现客户端接口的同时封装了服务对象。适配器接受客户端通过适配器接口发起的调用,并将其转换为被封装服务对象的调用。
Adapter:不需要封装任何对象,因为它同时继承了客户端和服务端的行为。适配功能在重写的方法中完成。最后生成的适配器可替代已有的客户端类进行使用。
我们使用一个常见的场景来描述一下:电脑插口
我们的 mac 电脑已经实现了 lighting 接口,但是我们手头上还有一台 Windows 电脑没有实现 lighting 接口,那么我们就需要一个适配器来帮助我们实现了。
// client.go 客户端代码
package main
import "fmt"
type Client struct{}
func (c *Client) InsertLightningConnectorIntoComputer(com Computer) {
fmt.Println("Client inserts Lightning connector into computer.")
com.InsertIntoLightningPort()
}
// computer.go 客户端接口
package main
type Computer interface {
InsertIntoLightningPort()
}
// mac.go 类似服务
package main
import "fmt"
type Mac struct{}
func (m *Mac) InsertIntoLightningPort() {
fmt.Println("Lightning connector is plugged into mac machine.")
}
// windows.go 未知服务,外部服务
package main
import "fmt"
type Windows struct{}
func (w *Windows) insertIntoUSBPort() {
fmt.Println("USB connector is plugged into windows machine.")
}
// windowsAdapter.go 适配器
package main
import "fmt"
type WindowsAdapter struct {
windowMachine *Windows
}
func (w *WindowsAdapter) InsertIntoLightningPort() {
fmt.Println("Adapter converts Lightning signal to USB.")
w.windowMachine.insertIntoUSBPort()
}
// main.go
package main
func main() {
client := &Client{}
mac := &Mac{}
client.InsertLightningConnectorIntoComputer(mac)
windowsMachine := &Windows{}
windowsMachineAdapter := &WindowsAdapter{
windowMachine: windowsMachine,
}
client.InsertLightningConnectorIntoComputer(windowsMachineAdapter)
}
output:
Client inserts Lightning connector into computer.
Lightning connector is plugged into mac machine.
Client inserts Lightning connector into computer.
Adapter converts Lightning signal to USB.
USB connector is plugged into windows machine.