适配器模式(Adapter Pattern)

344 阅读2分钟

简介

适配器模式(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")
}