文章目录

八、adapter 适配器模式
https://refactoringguru.cn/design-patterns/adapter
通常用于老旧系统, 或第三方系统, 提供一层适配器或插件, 做协议转换
PS: 如果开发新系统, 各层之间的解耦, 成为 bridge 桥接模式. 而如果是老系统则称为 adapter 适配器模式. 本质是一样的. 都是通过添加中间层实现的.
源码路径:godp/08adapter at master · datager/godp · GitHub
8.1 convert_lightning_to_usb
https://refactoringguru.cn/design-patterns/adapter/go/example
08adapter/081convert_lightning_to_usb
├── adapter.go
├── client.go
├── client_test.go
├── computer.go
└── readme.md
8.1.1 client_test.go
package _81convert_lightning_to_usb
import "testing"
/*
=== RUN TestClient
insert lighting into computer
mac: insert into lightning port
insert lighting into computer
适配器: 将雷电口转换为USB口
windows: insert into usb port
--- PASS: TestClient (0.00s)
PASS
*/
func TestClient(t *testing.T) {
mac := &mac{}
windowsAdapter := &windowsAdapter{windowsComputer: &windows{}}
c := &client{}
c.InsertLightningIntoComputer(mac)
c.InsertLightningIntoComputer(windowsAdapter)
}
8.1.2 client.go
package _81convert_lightning_to_usb
import "fmt"
type client struct {
}
func (c *client) InsertLightningIntoComputer(computer computer) {
fmt.Println("insert lighting into computer")
computer.InsertIntoLightningPort()
}
8.1.3 computer.go
package _81convert_lightning_to_usb
import "fmt"
type computer interface {
InsertIntoLightningPort()
}
type mac struct{}
func (c *mac) InsertIntoLightningPort() {
fmt.Println("mac: insert into lightning port")
}
type windows struct{}
func (c *windows) InsertIntoUSBPort() {
// windows 只支持 usb 口, 不支持雷电口
fmt.Println("windows: insert into usb port")
}
8.1.4 adapter.go
package _81convert_lightning_to_usb
import "fmt"
type windowsAdapter struct {
windowsComputer *windows
}
func (a *windowsAdapter) InsertIntoLightningPort() {
fmt.Println("适配器: 将雷电口转换为USB口")
a.windowsComputer.InsertIntoUSBPort()
}
8.2 huawei_od_user_manager
参考 <设计模式之禅> 第 19 章
如果已有一个用户管理系统(如华为), 还希望对接第三方的外包管理系统(如od), 两个系统的接口, 数据肯定不一致.
既然是老系统, 时间紧任务重, 推倒重来肯定来不及, 所以可以写一个 adapter(适配器), 做协议转换.
adapter 就是俗称的包一层, 封装一层. 通常是相同的功能, 但协议不同, 需要加一个中间层做中转.
08adapter/082huawei_user_manager
├── huawei_user_manager.go
├── huawei_user_manager_test.go
├── od
│ ├── account.go
│ └── account_manager.go
├── od_adapter.go
├── readmd.md
└── user.go
8.2.1 huawei_user_manager_test.go
package _82huawei_user_manager
import (
"fmt"
"github.com/stretchr/testify/require"
"godp/08adapter/082huawei_user_manager/od"
"testing"
)
/*
=== RUN TestHuaweiUserManagerGetAll
获取huawei本部员工
获取od员工
创建huawei od适配器
通过适配器, 获取huawei od员工
获取全部员工
--- PASS: TestHuaweiUserManagerGetAll (0.00s)
PASS
*/
func TestHuaweiUserManagerGetAll(t *testing.T) {
fmt.Println("获取huawei本部员工")
huaweiUsers := []user{
&huaweiUser{id: "1", name: "CEO", departmentID: 0},
&huaweiUser{id: "2", name: "CTO", departmentID: 0},
&huaweiUser{id: "3", name: "CFO", departmentID: 0},
}
hum := NewHuaweiUserManager(huaweiUsers)
us1 := hum.GetAll()
fmt.Println("获取od员工")
odAccounts := []od.Account{
od.Account{ID: 881, Name: "CloudStaff1", PhoneNumber: "19900009999", CompanyToWorkFor: "huawei"},
od.Account{ID: 882, Name: "CloudStaff2", PhoneNumber: "19911119999", CompanyToWorkFor: "huawei"},
od.Account{ID: 883, Name: "AIStaff3", PhoneNumber: "19922229999", CompanyToWorkFor: "google"},
od.Account{ID: 884, Name: "OSStaff4", PhoneNumber: "19933339999", CompanyToWorkFor: "microsoft"},
}
om := od.NewAccountManager(odAccounts)
fmt.Println("创建huawei od适配器")
odAdapter := NewHuaweiOdUserManagerAdapter(om)
fmt.Println("通过适配器, 获取huawei od员工")
us2 := odAdapter.GetAll()
fmt.Println("获取全部员工")
us := append(us1, us2...)
require.Len(t, us, 3+2)
ids := make([]string, 0)
for _, u := range us {
ids = append(ids, u.ID())
}
require.Contains(t, ids, "1")
require.Contains(t, ids, "2")
require.Contains(t, ids, "3")
require.Contains(t, ids, "881")
require.Contains(t, ids, "882")
require.NotContains(t, ids, "883")
require.NotContains(t, ids, "884")
}
8.2.2 huawei_user_manager.go
package _82huawei_user_manager
type userManager interface {
GetAll() []user
}
type huaweiUserManager struct {
users []user
}
func NewHuaweiUserManager(users []user) userManager {
return &huaweiUserManager{users: users}
}
func (hum *huaweiUserManager) GetAll() []user {
return hum.users
}
8.2.3 od_adapter.go
package _82huawei_user_manager
import (
"godp/08adapter/082huawei_user_manager/od"
"strconv"
)
const (
huaweiCompanyName = "huawei"
huaweiODDepartmentID = 3
)
// huawei 的 od 员工适配器
type huaweiOdUserManagerAdapter struct {
odManager od.AccountManager
}
func NewHuaweiOdUserManagerAdapter(odManager od.AccountManager) userManager {
return &huaweiOdUserManagerAdapter{
odManager: odManager,
}
}
// GetAll 获取 huawei 的 od 员工
func (oma *huaweiOdUserManagerAdapter) GetAll() []user {
huaweiUsers := make([]user, 0)
odAccounts := oma.odManager.GetAll()
for _, ac := range odAccounts {
if ac.CompanyToWorkFor != huaweiCompanyName {
continue
}
huaweiUsers = append(huaweiUsers, &huaweiUser{
id: strconv.Itoa(ac.ID),
name: ac.Name,
departmentID: huaweiODDepartmentID,
})
}
return huaweiUsers
}
8.2.4 od/account.go
package od
// Account 是 od 的 员工定义
type Account struct {
ID int
Name string
PhoneNumber string
CompanyToWorkFor string // 为哪家公司工作, 如 "huawei"
}
8.2.5 od/account_manager.go
package od
type AccountManager struct {
accounts []Account
}
func NewAccountManager(accounts []Account) AccountManager {
return AccountManager{accounts: accounts}
}
func (am *AccountManager) GetAll() []Account {
return am.accounts
}
1514

被折叠的 条评论
为什么被折叠?



