简介
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁,结合两个不同接口的功能。这种设计类型的属于结构型模式。举个日常生活中的例子可能比较好理解:usb转换type-c的接口就是应用适配器的原理
应用
- 功能接口整合,并对外提供统一接口。例如:企业内部的沟通工具有钉钉和企业微信,如果封装一个服务既能够发钉钉的消息又能发企业微信的消息,则需要对两个工具的接口进行整合(例如:客户端的初始化接口),并对外提供统一的初始化接口,则这里就需要用到了适配器
- 适配不同格式数据
实现
- 定义适配器接口 type AdapterInterfaceName interface {AdapterFunName(...) }
- 相关适配器的struct,实现接口的方法
示例
Chatops是整合了钉钉和企业微信的沟通工具,钉钉和企业微信都有各自不同的客户端初始化接口,则需要使用适配器来统一的初始化接口,并对外暴露。对于调用者来说都可以使用同一个初始化方法进行客户端初始化 适配器定义:
package adapter
import (
"fmt"
"reflect"
)
// 定义沟通客户端工具接口
type ChatClient interface {
Init(accessToken, appID string) error
}
// 定义钉钉工具
type DingTalk struct {
}
// 初始化钉钉工具
func (d *DingTalk) InitDingTalk(accessToken, appID string) error {
fmt.Println("init ding talk success")
return nil
}
// 钉钉工具适配器
type DingTalkAdapter struct {
Client DingTalk
}
// 钉钉工具适配器实现了ChatClient的init方法
func (a *DingTalkAdapter) Init(accessToken, appID string) error {
return a.Client.InitDingTalk(accessToken, appID)
}
// 定义企业微信工具
type WeiChat struct {
}
// 初始化企业微信工具
func (w *WeiChat) InitWeiChat(accessToken, appID string) error {
fmt.Println("init wei chat success")
return nil
}
// 定义企业微信工具适配器
type WeiChatAdapter struct {
Client WeiChat
}
// 企业微信工具适配器实现ChatClient的init方法
func (a *WeiChatAdapter) Init(accessToken, appID string) error {
return a.Client.InitWeiChat(accessToken, appID)
}
// 定义 chatops 工具
type ChatOps struct {
Client ChatClient
}
// 新建 chatops 工具
func NewChatOps(chatType reflect.Type) ChatClient {
return reflect.New(chatType).Interface().(ChatClient)
}
// 初始化钉钉或企业微信的客户端
func (c *ChatOps) InitClient(accessToken, appID string) error {
return c.Client.Init(accessToken, appID)
}
调用适配器:
package main
import (
"github.com/design/pattern/adapter"
"reflect"
)
func main() {
// 适配器模式
chatOps := adapter.NewChatOps(reflect.TypeOf(adapter.DingTalkAdapter{}))
chatOps.Init("token", "appID")
}