大家好,我是追麾(hui)。
这是Go的设计模式第四篇,这篇主要分享适配器模式,桥模式,组合模式。下面我们来看具体模式。
业界适配器模式定义:适配器(Adapter)指将某种接口或数据结构转换为客户端期望的类型,使得不兼容的类或对象能够一起协作。
适配器模式优缺点
适配器模式的应用场景
Go适配器模式实现方式
适配器模式(Adapter)包含以下主要角色。
适配器模式在我所接触的业务中,一个是支付SDK的集成形成同一个支付接口调用,聚合广告SDK的集成形成统一广告接口调用。下面我们来具体看示例应用。通过适配器实现支付宝SDK和微信SDK的集成。
package main
import "fmt"
func main() {
// 初始化对接接口
var t TargetInterface
// 同时调用支付宝和微信支付
t = &NewAdapter{
AlipayInterface: &AlipayPay{},
WeixinPayInterface: &WeixinPay{},
}
// 这里业务中基于一个用户同时只能调用一种支付方式。
t.DealDiffPay("weixinpay", 99)
t.DealDiffPay("alipay", 100)
}
// 支付宝支付SDK
type AlipayInterface interface {
Pay(money int)
}
type AlipayPay struct {
}
func (a *AlipayPay) Pay(money int) {
fmt.Println("这里是支付宝支付:", "费用是:", money)
}
// 微信支付SDK
type WeixinPayInterface interface {
WXPay(money int)
}
type WeixinPay struct {
}
func (a *WeixinPay) WXPay(money int) {
fmt.Println("这里是微信支付:", "费用是:", money)
}
// 目标接口,能支持传入支付宝或者微信支付进行支付
type TargetInterface interface {
DealDiffPay(payType string, money int)
}
//自己的adapter,实现微信和支付宝支付,
type NewAdapter struct {
AlipayInterface
WeixinPayInterface
}
func (n *NewAdapter) DealDiffPay(payType string, money int) {
if payType == "alipay" {
n.AlipayInterface.Pay(money)
} else if payType == "weixinpay" {
n.WeixinPayInterface.WXPay(money)
}
}
业界桥接模式定义:桥(Bridge)使用组合关系将代码的实现层和抽象层分离,让实现层与抽象层代码可以分别自由变化。
桥接模式优缺点
桥接模式的应用场景
Go桥接模式实现方式
关于上面我们看了桥接模式的定义,自己分离抽象和实现,这个抽象是指对象的抽象,这类对象的总称。实现这个就比较简单,是指具体干啥,是什么。我们具体两个例子,我们现在业界直播非常火,我们要送礼给主播,把送礼当成是一个对象抽象,比如送带水晶黄色皇冠,蓝色飞机啥的是具体的实现。
桥接模式的结构:
好了,下面我们来具体讲解一下例子。
package main
import (
"fmt"
)
func main() {
// 送一个蓝色的带水晶的皇冠
color := Blue{}
crystal := Crystal{}
c := Crown{
Color: &color,
DressUp: &crystal,
}
c.SendGift()
// 送一个红色的飞机
color2 := Red{}
p := Plane{
Color: &color2,
DressUp: nil,
}
p.SendGift()
}
// 颜色
type Color interface {
Use()
}
// 红色
type Red struct {
}
func (r *Red) Use() {
fmt.Println("use red color")
}
// 蓝色
type Blue struct {
}
func (b *Blue) Use() {
fmt.Println("use blue color")
}
// 装扮
type DressUp interface {
Decorate()
}
// 水晶
type Crystal struct {
}
func (c *Crystal) Decorate() {
fmt.Println("use crystal dress up")
}
// 抽象类,
type Abstraction interface {
SendGift()
}
// 飞机
type Plane struct {
Color
DressUp
}
func (p *Plane) SendGift() {
p.Use()
if p.DressUp != nil {
p.DressUp.Decorate()
}
fmt.Println("送飞机礼物")
}
// 皇冠
type Crown struct {
Color
DressUp
}
func (c *Crown) SendGift() {
c.Use()
if c.DressUp != nil {
c.DressUp.Decorate()
}
fmt.Println("送皇冠礼物")
}
业界组合模式模式定义:组合(Composite)是指使用组合和继承关系将聚合体及其组成元素分解成树状结构,以便客户端在不需要区分聚合体或组成元素类型的情况下使用统一的接口操作它们。
组合模式模式优缺点
组合模式模式的应用场景
Go组合模式模式实现方式
组合模式包含以下主要角色。
我们就拿现今社会的等级划分来讲述实现组合模式实现。下面我们来具体看代码实现。
package main
import (
"container/list"
"fmt"
"reflect"
"strconv"
)
func main() {
// 创建现今社会的等级
mainLevel := NewPeopleLevel("高层领导干部", "社会上层", 1000000000)
// 中上层
level11 := NewPeopleLevel("中层领导干部", "中上层", 10000000)
level12 := NewPeopleLevel("大企业中层管理人员", "中上层", 10000000)
// 中中层
level1111 := NewPeopleLevel("小企业主", "中中层", 10000)
level1112 := NewPeopleLevel("办事人员", "中中层", 10000)
// 中下层
level111111 := NewPeopleLevel("农民工程序员", "中下层", 1000)
level111112 := NewPeopleLevel("个体服务者", "中下层", 1000)
// 底层
level1111111 := NewPeopleLevel("失业人员", "底层", 100)
//组成当前人类等级
// 上层添加中上层
mainLevel.Add(level11)
mainLevel.Add(level12)
// 中上层添加中中层
level11.Add(level1111)
level12.Add(level1112)
// 中中层添加中下层
level1111.Add(level111111)
level1112.Add(level111112)
// 中下层添加底层
level111111.Add(level1111111)
// 打印今社会的等级
fmt.Println(mainLevel.ToString())
for i := mainLevel.SubList.Front(); i != nil; i = i.Next() {
em := i.Value.(*PeopleLevel)
fmt.Println(em.ToString())
for j := i.Value.(*PeopleLevel).SubList.Front(); j != nil; j = j.Next() {
em := j.Value.(*PeopleLevel)
fmt.Println(em.ToString())
for k := j.Value.(*PeopleLevel).SubList.Front(); k != nil; k = k.Next() {
em := k.Value.(*PeopleLevel)
fmt.Println(em.ToString())
for l := k.Value.(*PeopleLevel).SubList.Front(); l != nil; l = l.Next() {
em := l.Value.(*PeopleLevel)
fmt.Println(em.ToString())
}
}
}
}
}
// 人等级 对象
type PeopleLevel struct {
Name string
Role string
IncomeLevel int
SubList *list.List
}
// 添加子等级
func (p *PeopleLevel) Add(o *PeopleLevel) {
p.SubList.PushBack(o)
}
// 删除一个等级
func (p *PeopleLevel) Remove(o *PeopleLevel) {
for i := p.SubList.Front(); i != nil; i = i.Next() {
if reflect.DeepEqual(i.Value, o) {
p.SubList.Remove(i)
}
}
}
// 获取等级列表
func (p *PeopleLevel) GetSubList() *list.List {
return p.SubList
}
// 获取等级的string信息
func (p *PeopleLevel) ToString() string {
return "[ Name: " + p.Name + ", Role: " + p.Role + ", IncomeLevel: " + strconv.Itoa(p.IncomeLevel) + " ]"
}
// 实例化 人类等级对象
func NewPeopleLevel(name, role string, income int) *PeopleLevel {
sub := list.New()
return &PeopleLevel{
Name: name,
Role: role,
IncomeLevel: income,
SubList: sub,
}
}
现今社会的等级划分结果如下:
[ Name: 高层领导干部, Role: 社会上层, IncomeLevel: 1000000000 ]
[ Name: 中层领导干部, Role: 中上层, IncomeLevel: 10000000 ]
[ Name: 小企业主, Role: 中中层, IncomeLevel: 10000 ]
[ Name: 农民工程序员, Role: 中下层, IncomeLevel: 1000 ]
[ Name: 失业人员, Role: 底层, IncomeLevel: 100 ]
[ Name: 大企业中层管理人员, Role: 中上层, IncomeLevel: 10000000 ]
[ Name: 办事人员, Role: 中中层, IncomeLevel: 10000 ]
[ Name: 个体服务者, Role: 中下层, IncomeLevel: 1000 ]