版权声明

作者:腾讯技术工程

链接:https://zhuanlan.zhihu.com/p/437626980

来源:知乎

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

如有侵权,请联系[[commuinty@eolink.com](mailto:commuinty@eolink.com)](mailto:**[commuinty@eolink.com](mailto:commuinty@eolink.com)**)删除。

11. 享元模式

flyweight.go


// package flyweight 享元模式。通过抽离出被大量创建的对象中的不易变的属性,达到减少对象个数、降低内存的效果。
// 假设一个象棋游戏,游戏大厅中有百万棋局同时启动,那么会产生非常多的棋子和棋局对象,通过抽离出不变的棋子的属性,来降低内存。
package flyweight

import (
 "fmt"
 "sync"
)

// Color 棋子的颜色
type Color string

const (
 // ColorBlack 黑色
 ColorBlack Color = "黑色"
 // ColorRed 红色
 ColorRed Color = "红色"
)

var (
 // once 保证只执行一次
 once sync.Once

 // instance 单例对象
 PieceUnitFactory *pieceUnitFactory
)

// GetPieceUnitFactory 获取单例对象。 注:必须使用指针对象,否则会在返回时,拷贝一份,对象就不是同一个了。
func GetPieceUnitFactory() *pieceUnitFactory {
 once.Do(func() {
  PieceUnitFactory = &pieceUnitFactory{}
  PieceUnitFactory.PieceUnitMap = make(map[int]PieceUnit)
  PieceUnitFactory.init()
 })
 return PieceUnitFactory
}

// PieceUnit 棋子享元
type PieceUnit struct {
 // ID 唯一标识
 ID int
 // Text 棋子的文字
 Text string
 // Color 棋子的颜色
 Color Color
}

// pieceUnitFactory 棋子享元对象工厂
type pieceUnitFactory struct {
 //sync.RWMutex
 // PieceUnitMap 棋子id与享元对象的对应关系的map
 PieceUnitMap map[int]PieceUnit
}

// init 初始化工厂
func (factory pieceUnitFactory) init() {
 // 不需要锁,因为通过once.Do创建
 //factory.Lock()
 //defer factory.Unlock()

 factory.PieceUnitMap[1] = PieceUnit{1, "將", ColorBlack}
 factory.PieceUnitMap[2] = PieceUnit{2, "帥", ColorRed}
 factory.PieceUnitMap[3] = PieceUnit{3, "馬", ColorBlack}
 factory.PieceUnitMap[4] = PieceUnit{4, "傌", ColorRed}
 factory.PieceUnitMap[5] = PieceUnit{5, "馬", ColorBlack}
 factory.PieceUnitMap[6] = PieceUnit{6, "傌", ColorRed}
 factory.PieceUnitMap[7] = PieceUnit{7, "砲", ColorBlack}
 factory.PieceUnitMap[8] = PieceUnit{8, "炮", ColorRed}
 factory.PieceUnitMap[9] = PieceUnit{9, "砲", ColorBlack}
 factory.PieceUnitMap[10] = PieceUnit{10, "炮", ColorRed}
 factory.PieceUnitMap[11] = PieceUnit{11, "車", ColorBlack}
 factory.PieceUnitMap[12] = PieceUnit{12, "俥", ColorRed}
 factory.PieceUnitMap[13] = PieceUnit{13, "車", ColorBlack}
 factory.PieceUnitMap[14] = PieceUnit{14, "俥", ColorRed}
 factory.PieceUnitMap[15] = PieceUnit{15, "士", ColorBlack}
 factory.PieceUnitMap[16] = PieceUnit{16, "仕", ColorRed}
 factory.PieceUnitMap[17] = PieceUnit{17, "士", ColorBlack}
 factory.PieceUnitMap[18] = PieceUnit{18, "仕", ColorRed}
 factory.PieceUnitMap[19] = PieceUnit{19, "象", ColorBlack}
 factory.PieceUnitMap[20] = PieceUnit{20, "相", ColorRed}
 factory.PieceUnitMap[21] = PieceUnit{21, "象", ColorBlack}
 factory.PieceUnitMap[22] = PieceUnit{22, "相", ColorRed}
 factory.PieceUnitMap[23] = PieceUnit{23, "卒", ColorBlack}
 factory.PieceUnitMap[24] = PieceUnit{24, "兵", ColorRed}
 factory.PieceUnitMap[25] = PieceUnit{25, "卒", ColorBlack}
 factory.PieceUnitMap[26] = PieceUnit{26, "兵", ColorRed}
 factory.PieceUnitMap[27] = PieceUnit{27, "卒", ColorBlack}
 factory.PieceUnitMap[28] = PieceUnit{28, "兵", ColorRed}
 factory.PieceUnitMap[29] = PieceUnit{29, "卒", ColorBlack}
 factory.PieceUnitMap[30] = PieceUnit{30, "兵", ColorRed}
 factory.PieceUnitMap[31] = PieceUnit{31, "卒", ColorBlack}
 factory.PieceUnitMap[32] = PieceUnit{32, "兵", ColorRed}

}

// GetChessPieceUnit 根据id获取棋子享元对象
func (factory pieceUnitFactory) GetChessPieceUnit(id int) PieceUnit {
 return factory.PieceUnitMap[id]
}

// Piece 棋子
type Piece struct {
 // PieceUnit
 PieceUnit
 // PositionX
 PositionX int
 // PositionY
 PositionY int
}

// ChessBoard 棋盘
type ChessBoard struct {
 // sync.RWMutex 嵌套锁
 sync.RWMutex
 // ChessPieceMap 棋子id与棋子对象的对应关系的map
 ChessPieceMap map[int]*Piece
}

//init 初始化棋局。 You must call this。
func (board *ChessBoard) Init() {
 // 加锁
 board.Lock()
 defer board.Unlock()
 // 获取棋子享元工厂
 unitFactory := GetPieceUnitFactory()
 board.ChessPieceMap = make(map[int]*Piece)
 board.ChessPieceMap[1] = &Piece{
  PieceUnit: unitFactory.GetChessPieceUnit(1),
  PositionX: 0,
  PositionY: 1,
 }
 board.ChessPieceMap[2] = &Piece{
  PieceUnit: unitFactory.GetChessPieceUnit(2),
  PositionX: 5,
  PositionY: 1,
 }
 board.ChessPieceMap[3] = &Piece{
  PieceUnit: unitFactory.GetChessPieceUnit(3),
  PositionX: 2,
  PositionY: 8,
 }
 //......
}

// Move 棋盘上移动棋子
func (board *ChessBoard) Move(id int, positionX, positionY int) {
 board.ChessPieceMap[id].PositionX = positionX
 board.ChessPieceMap[id].PositionY = positionY
 fmt.Println(fmt.Sprintf("%s的%s被移动到了(%d,%d)的位置", board.ChessPieceMap[id].Color, board.ChessPieceMap[id].Text, positionX, positionY))
}


flyweight_test.go


package flyweight

import (
 "testing"
)

func Test(t *testing.T) {
 t.Run("flyweight", Flyweight)
}

func Flyweight(t *testing.T) {
 board1 := ChessBoard{}
 board1.Init()
 board1.Move(1, 10, 20)

 board2 := ChessBoard{}
 board2.Init()
 board2.Move(2, 6, 6)
}

12. 备忘录模式

memorandum.go


// package memorandum 备忘录模式
package memorandum

import "fmt"

// Originator 发起者,负责创建备忘录,可以记录和恢复本身的状态。
type Originator struct {
 // State 当前状态
 State string
}

// restoreMemento 将发起人的状态更新为备忘录的状态,即恢复至备忘录
func (originator *Originator) restoreMemento(memento Memento) {
 originator.State = memento.state
}

// createMemento 使用发起者当前的状态,创建备忘录
func (originator *Originator) createMemento() Memento {
 return Memento{originator.State}
}

// print 打印发起者的状态
func (originator *Originator) print() {
 fmt.Println(fmt.Sprintf("originator的状态为%s", originator.State))
}

// Memento 备忘录,存储发起者的状态,防止除发起者之外的人访问备忘录
type Memento struct {
 // state 当前状态,不可导出
 state string
}

// Caretaker 管理者,负责存储备忘录,但不对备忘录操作
type Caretaker struct {
 // memento 备忘录对象
 memento Memento
}


memorandum_test.go


package memorandum

import "testing"

func Test(t *testing.T) {
 t.Run("memorandum", Memorandum)
}

func Memorandum(t *testing.T) {
 // 发起者初始状态
 originator := Originator{}
 originator.State = "start"
 originator.print()

 // 设置备忘录
 caretaker := Caretaker{}
 caretaker.memento = originator.createMemento()
 originator.State = "Stage Two"
 originator.print()

 // 恢复为备忘录
 originator.restoreMemento(caretaker.memento)
 originator.print()
}

13. 观察者模式

observer.go


// package observer 观察者模式,以两种类型的观察者(可以有多个观察者)为例,向被观察者添加观察者,观察者完成操作后,通知观察者
package observer

import "fmt"

// Observer 观察者
type Observer interface {
 //notify 通知
 notify(sub Subject)
}

// BaseObserver 基础观察者
type BaseObserver struct {
 Name string
}

// TeacherObserver 老师观察者
type TeacherObserver struct {
 BaseObserver
}

// ParentObserver 家长观察者
type ParentObserver struct {
 BaseObserver
}

// notify 老师观察者,实现Observer接口
func (to TeacherObserver) notify(sub Subject) {
 fmt.Println(to.Name + "老师收到了作业")
}

// notify 家长观察者,实现Observer接口
func (to ParentObserver) notify(sub Subject) {
 fmt.Println(to.Name + "(家长)收到了作业")
}


subject.go

package observer

import "fmt"

//Subject 被观察者接口
type Subject interface {
 //通知观察者
 NotifyObservers()

 //添加观察者
 AddObserver(observer Observer)

 //批量添加观察者
 AddObservers(observers ...Observer)

 //移除观察者
 RemoveObserver(observer Observer)

 //移除全部观察者
 RemoveAllObservers()
}

// StudentSubject 学生被观察者,实现Subject接口
type StudentSubject struct {
 // observers 观察者们
 observers []Observer
}

// NotifyObservers 通知观察者 注:需要使用指针接收者,不然s.observers的值会为空
func (ss *StudentSubject) NotifyObservers() {
 fmt.Println("学生写完了作业,通知观察者们")
 for _, o := range ss.observers {
  //通知观察者
  o.notify(ss)
 }
}

// AddObserver 添加观察者
func (ss *StudentSubject) AddObserver(observer Observer) {
 ss.observers = append(ss.observers, observer)
}

// AddObservers 添加观察者列表
func (ss *StudentSubject) AddObservers(observers ...Observer) {
 ss.observers = append(ss.observers, observers...)
}

// RemoveObserver 移除观察者
func (ss *StudentSubject) RemoveObserver(observer Observer) {
 for i := 0; i < len(ss.observers); i++ {
  if ss.observers[i] == observer {
   ss.observers = append(ss.observers[:i], ss.observers[i+1:]...)
  }
 }
}

// RemoveAllObservers 移除全部观察者
func (ss *StudentSubject) RemoveAllObservers() {
 ss.observers = ss.observers[:0]
}


observer_test.go


package observer

import (
 "fmt"
 "testing"
)

func Test(t *testing.T) {
 t.Run("observer: ", NotifyObservers)
}

func NotifyObservers(t *testing.T) {
 var subject Subject
 subject = &StudentSubject{}

 var mathTeacherObserver, englishTeacherObserver, motherObserver, fatherObserver Observer
 mathTeacherObserver = &TeacherObserver{BaseObserver{"数学"}}
 englishTeacherObserver = &TeacherObserver{BaseObserver{"英语"}}
 motherObserver = &ParentObserver{BaseObserver{"妈妈"}}
 fatherObserver = &ParentObserver{BaseObserver{"爸爸"}}

 //只添加数学老师观察者,那么只有数学老师会收到作业完成通知
 fmt.Println("******只添加数学老师观察者,那么只有数学老师会收到作业完成通知******")
 subject.AddObserver(mathTeacherObserver)
 subject.NotifyObservers()
 fmt.Println()

 //又批量添加了英语老师、妈妈、爸爸,那么数学老师、英语老师、妈妈、爸爸,都会收到作业完成通知
 fmt.Println("******又批量添加了英语老师、妈妈、爸爸,那么数学老师、英语老师、妈妈、爸爸,都会收到作业完成通知******")
 subject.AddObservers(englishTeacherObserver, motherObserver, fatherObserver)
 subject.NotifyObservers()
 fmt.Println()

 //移除了妈妈观察者,那么只有数学老师、英语老师、爸爸,会收到作业完成通知
 fmt.Println("******移除了妈妈观察者,那么只有数学老师、英语老师、爸爸,会收到作业完成通知******")
 subject.RemoveObserver(motherObserver)
 subject.NotifyObservers()
 fmt.Println()

 //移除了所有观察者,那么不会有人收到作业完成通知
 fmt.Println("******移除了所有观察者,那么不会有人收到作业完成通知******")
 subject.RemoveAllObservers()
 subject.NotifyObservers()
 fmt.Println()
}

14. 代理模式

proxy.go


package proxy

import "fmt"

// Downloader 下载器接口
type Downloader interface {
 // Download 下载
 Download()
}

// ConcreteDownload 具体的下载结构体,实现Downloader接口
type ConcreteDownload struct {
 Url string
}

// Download 下载
func (download ConcreteDownload) Download() {
 fmt.Println(fmt.Sprintf("%s 在下载中", download.Url))
}

// DownloadProxy,下载代理,实现Downloader接口
type DownloadProxy struct {
 Url        string
 downloader Downloader
}

// Download 下载
func (proxy DownloadProxy) Download() {
 fmt.Println(fmt.Sprintf("准备开始下载%s", proxy.Url))
 proxy.downloader.Download()
 fmt.Println(fmt.Sprintf("下载%s完成", proxy.Url))
}


proxy_test.go


package proxy

import (
 "testing"
)

func Test(t *testing.T) {
 t.Run("proxy-statics: ", StaticsProxy)
}

func StaticsProxy(t *testing.T) {
 url := "http://baidu.com"
 download := &ConcreteDownload{Url: url}
 proxy := &DownloadProxy{
  Url:        url,
  downloader: download,
 }
 proxy.Download()
}

15. 责任链模式

responsibility_chain.go


/*
    package responsibility_chain 责任链模式,把多个处理器串成链,然后让请求在链上传递。
    以财务审批为例:
    Leader 直接上级只能审核500元以下的报销
 Director 总监只能审核5000元以下的报销
 CFO 首席财务官可以审核任意金额的报销
*/
package responsibility_chain

import "fmt"

// Manager 管理者接口
type Manager interface {
 // Review 审核
 Review(request Request) bool
}

// Request 报销请求
type Request struct {
 // Name 姓名
 Name string
 // Amount 金额
 Amount int
}

// Leader 直接上级只能审核500元以下的报销,实现Manager接口
type Leader struct{}

// Director 总监只能审核5000元以下的报销,实现Manager接口
type Director struct{}

// CFO 首席财务官可以审核任意金额的报销,实现Manager接口
type CFO struct{}

// Review Leader实现报销方法
func (leader Leader) Review(request Request) bool {
 if request.Amount < 500 {
  fmt.Println(fmt.Sprintf("leader 处理了%s的%d元报销", request.Name, request.Amount))
  return true
 }
 return false
}

// Review Director实现报销方法
func (director Director) Review(request Request) bool {
 if request.Amount < 5000 {
  fmt.Println(fmt.Sprintf("director 处理了%s的%d元报销", request.Name, request.Amount))
  return true
 }
 return false
}

// Review CFO实现报销方法
func (cfo CFO) Review(request Request) bool {
 fmt.Println(fmt.Sprintf("cfo 处理了%s的%d元报销", request.Name, request.Amount))
 return true
}

// HandlerChain 责任链处理器
type HandlerChain struct {
 // managers 责任链切片,不可导出
 managers []Manager
}

// AddHandler 责任链处理器对象,添加处理器。注:使用指针接收者,需要更改切片
func (chain *HandlerChain) AddHandler(manager Manager) {
 chain.managers = append(chain.managers, manager)
}

// AddHandlers 责任链处理器对象,批量添加处理器。注:使用指针接收者,需要更改切片
func (chain *HandlerChain) AddHandlers(managers ...Manager) {
 chain.managers = append(chain.managers, managers...)
}

// HandleRequest 责任链处理器对象,处理请求
func (chain *HandlerChain) HandleRequest(request Request) error {
 for _, manager := range chain.managers {
  result := manager.Review(request)
  // 如果result为true,则说明已经处理完成
  if result {
   return nil
  }
 }
 return fmt.Errorf("请求未被处理")
}


responsibility_chain_test.go


package responsibility_chain

import "testing"

func Test(t *testing.T) {
 t.Run("responsibility_chain_200: ", ChainOfResponsibility200)
 t.Run("responsibility_chain_3000: ", ChainOfResponsibility3000)
 t.Run("responsibility_chain_6000: ", ChainOfResponsibility6000)
}

// ChainOfResponsibility200 200元报销请求
func ChainOfResponsibility200(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandler(leader)
 handlerChain.AddHandler(director)
 handlerChain.AddHandler(cfo)

 request := Request{
  Name:   "kay",
  Amount: 200,
 }
 handlerChain.HandleRequest(request)
}

// ChainOfResponsibility3000 3000元报销请求
func ChainOfResponsibility3000(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandlers(leader, director, cfo)

 request := Request{
  Name:   "kay",
  Amount: 3000,
 }
 handlerChain.HandleRequest(request)
}

// ChainOfResponsibility6000 6000元报销请求
func ChainOfResponsibility6000(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandlers(leader, director, cfo)

 request := Request{
  Name:   "kay",
  Amount: 6000,
 }
 handlerChain.HandleRequest(request)
}

16. 简单工厂模式

responsibility_chain.go


/*
    package responsibility_chain 责任链模式,把多个处理器串成链,然后让请求在链上传递。
    以财务审批为例:
    Leader 直接上级只能审核500元以下的报销
 Director 总监只能审核5000元以下的报销
 CFO 首席财务官可以审核任意金额的报销
*/
package responsibility_chain

import "fmt"

// Manager 管理者接口
type Manager interface {
 // Review 审核
 Review(request Request) bool
}

// Request 报销请求
type Request struct {
 // Name 姓名
 Name string
 // Amount 金额
 Amount int
}

// Leader 直接上级只能审核500元以下的报销,实现Manager接口
type Leader struct{}

// Director 总监只能审核5000元以下的报销,实现Manager接口
type Director struct{}

// CFO 首席财务官可以审核任意金额的报销,实现Manager接口
type CFO struct{}

// Review Leader实现报销方法
func (leader Leader) Review(request Request) bool {
 if request.Amount < 500 {
  fmt.Println(fmt.Sprintf("leader 处理了%s的%d元报销", request.Name, request.Amount))
  return true
 }
 return false
}

// Review Director实现报销方法
func (director Director) Review(request Request) bool {
 if request.Amount < 5000 {
  fmt.Println(fmt.Sprintf("director 处理了%s的%d元报销", request.Name, request.Amount))
  return true
 }
 return false
}

// Review CFO实现报销方法
func (cfo CFO) Review(request Request) bool {
 fmt.Println(fmt.Sprintf("cfo 处理了%s的%d元报销", request.Name, request.Amount))
 return true
}

// HandlerChain 责任链处理器
type HandlerChain struct {
 // managers 责任链切片,不可导出
 managers []Manager
}

// AddHandler 责任链处理器对象,添加处理器。注:使用指针接收者,需要更改切片
func (chain *HandlerChain) AddHandler(manager Manager) {
 chain.managers = append(chain.managers, manager)
}

// AddHandlers 责任链处理器对象,批量添加处理器。注:使用指针接收者,需要更改切片
func (chain *HandlerChain) AddHandlers(managers ...Manager) {
 chain.managers = append(chain.managers, managers...)
}

// HandleRequest 责任链处理器对象,处理请求
func (chain *HandlerChain) HandleRequest(request Request) error {
 for _, manager := range chain.managers {
  result := manager.Review(request)
  // 如果result为true,则说明已经处理完成
  if result {
   return nil
  }
 }
 return fmt.Errorf("请求未被处理")
}


responsibility_chain_test.go


package responsibility_chain

import "testing"

func Test(t *testing.T) {
 t.Run("responsibility_chain_200: ", ChainOfResponsibility200)
 t.Run("responsibility_chain_3000: ", ChainOfResponsibility3000)
 t.Run("responsibility_chain_6000: ", ChainOfResponsibility6000)
}

// ChainOfResponsibility200 200元报销请求
func ChainOfResponsibility200(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandler(leader)
 handlerChain.AddHandler(director)
 handlerChain.AddHandler(cfo)

 request := Request{
  Name:   "kay",
  Amount: 200,
 }
 handlerChain.HandleRequest(request)
}

// ChainOfResponsibility3000 3000元报销请求
func ChainOfResponsibility3000(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandlers(leader, director, cfo)

 request := Request{
  Name:   "kay",
  Amount: 3000,
 }
 handlerChain.HandleRequest(request)
}

// ChainOfResponsibility6000 6000元报销请求
func ChainOfResponsibility6000(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandlers(leader, director, cfo)

 request := Request{
  Name:   "kay",
  Amount: 6000,
 }
 handlerChain.HandleRequest(request)
}

17. 单例模式

responsibility_chain.go


/*
    package responsibility_chain 责任链模式,把多个处理器串成链,然后让请求在链上传递。
    以财务审批为例:
    Leader 直接上级只能审核500元以下的报销
 Director 总监只能审核5000元以下的报销
 CFO 首席财务官可以审核任意金额的报销
*/
package responsibility_chain

import "fmt"

// Manager 管理者接口
type Manager interface {
 // Review 审核
 Review(request Request) bool
}

// Request 报销请求
type Request struct {
 // Name 姓名
 Name string
 // Amount 金额
 Amount int
}

// Leader 直接上级只能审核500元以下的报销,实现Manager接口
type Leader struct{}

// Director 总监只能审核5000元以下的报销,实现Manager接口
type Director struct{}

// CFO 首席财务官可以审核任意金额的报销,实现Manager接口
type CFO struct{}

// Review Leader实现报销方法
func (leader Leader) Review(request Request) bool {
 if request.Amount < 500 {
  fmt.Println(fmt.Sprintf("leader 处理了%s的%d元报销", request.Name, request.Amount))
  return true
 }
 return false
}

// Review Director实现报销方法
func (director Director) Review(request Request) bool {
 if request.Amount < 5000 {
  fmt.Println(fmt.Sprintf("director 处理了%s的%d元报销", request.Name, request.Amount))
  return true
 }
 return false
}

// Review CFO实现报销方法
func (cfo CFO) Review(request Request) bool {
 fmt.Println(fmt.Sprintf("cfo 处理了%s的%d元报销", request.Name, request.Amount))
 return true
}

// HandlerChain 责任链处理器
type HandlerChain struct {
 // managers 责任链切片,不可导出
 managers []Manager
}

// AddHandler 责任链处理器对象,添加处理器。注:使用指针接收者,需要更改切片
func (chain *HandlerChain) AddHandler(manager Manager) {
 chain.managers = append(chain.managers, manager)
}

// AddHandlers 责任链处理器对象,批量添加处理器。注:使用指针接收者,需要更改切片
func (chain *HandlerChain) AddHandlers(managers ...Manager) {
 chain.managers = append(chain.managers, managers...)
}

// HandleRequest 责任链处理器对象,处理请求
func (chain *HandlerChain) HandleRequest(request Request) error {
 for _, manager := range chain.managers {
  result := manager.Review(request)
  // 如果result为true,则说明已经处理完成
  if result {
   return nil
  }
 }
 return fmt.Errorf("请求未被处理")
}


responsibility_chain_test.go


package responsibility_chain

import "testing"

func Test(t *testing.T) {
 t.Run("responsibility_chain_200: ", ChainOfResponsibility200)
 t.Run("responsibility_chain_3000: ", ChainOfResponsibility3000)
 t.Run("responsibility_chain_6000: ", ChainOfResponsibility6000)
}

// ChainOfResponsibility200 200元报销请求
func ChainOfResponsibility200(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandler(leader)
 handlerChain.AddHandler(director)
 handlerChain.AddHandler(cfo)

 request := Request{
  Name:   "kay",
  Amount: 200,
 }
 handlerChain.HandleRequest(request)
}

// ChainOfResponsibility3000 3000元报销请求
func ChainOfResponsibility3000(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandlers(leader, director, cfo)

 request := Request{
  Name:   "kay",
  Amount: 3000,
 }
 handlerChain.HandleRequest(request)
}

// ChainOfResponsibility6000 6000元报销请求
func ChainOfResponsibility6000(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandlers(leader, director, cfo)

 request := Request{
  Name:   "kay",
  Amount: 6000,
 }
 handlerChain.HandleRequest(request)
}

18. 状态模式

responsibility_chain.go


/*
    package responsibility_chain 责任链模式,把多个处理器串成链,然后让请求在链上传递。
    以财务审批为例:
    Leader 直接上级只能审核500元以下的报销
 Director 总监只能审核5000元以下的报销
 CFO 首席财务官可以审核任意金额的报销
*/
package responsibility_chain

import "fmt"

// Manager 管理者接口
type Manager interface {
 // Review 审核
 Review(request Request) bool
}

// Request 报销请求
type Request struct {
 // Name 姓名
 Name string
 // Amount 金额
 Amount int
}

// Leader 直接上级只能审核500元以下的报销,实现Manager接口
type Leader struct{}

// Director 总监只能审核5000元以下的报销,实现Manager接口
type Director struct{}

// CFO 首席财务官可以审核任意金额的报销,实现Manager接口
type CFO struct{}

// Review Leader实现报销方法
func (leader Leader) Review(request Request) bool {
 if request.Amount < 500 {
  fmt.Println(fmt.Sprintf("leader 处理了%s的%d元报销", request.Name, request.Amount))
  return true
 }
 return false
}

// Review Director实现报销方法
func (director Director) Review(request Request) bool {
 if request.Amount < 5000 {
  fmt.Println(fmt.Sprintf("director 处理了%s的%d元报销", request.Name, request.Amount))
  return true
 }
 return false
}

// Review CFO实现报销方法
func (cfo CFO) Review(request Request) bool {
 fmt.Println(fmt.Sprintf("cfo 处理了%s的%d元报销", request.Name, request.Amount))
 return true
}

// HandlerChain 责任链处理器
type HandlerChain struct {
 // managers 责任链切片,不可导出
 managers []Manager
}

// AddHandler 责任链处理器对象,添加处理器。注:使用指针接收者,需要更改切片
func (chain *HandlerChain) AddHandler(manager Manager) {
 chain.managers = append(chain.managers, manager)
}

// AddHandlers 责任链处理器对象,批量添加处理器。注:使用指针接收者,需要更改切片
func (chain *HandlerChain) AddHandlers(managers ...Manager) {
 chain.managers = append(chain.managers, managers...)
}

// HandleRequest 责任链处理器对象,处理请求
func (chain *HandlerChain) HandleRequest(request Request) error {
 for _, manager := range chain.managers {
  result := manager.Review(request)
  // 如果result为true,则说明已经处理完成
  if result {
   return nil
  }
 }
 return fmt.Errorf("请求未被处理")
}


responsibility_chain_test.go


package responsibility_chain

import "testing"

func Test(t *testing.T) {
 t.Run("responsibility_chain_200: ", ChainOfResponsibility200)
 t.Run("responsibility_chain_3000: ", ChainOfResponsibility3000)
 t.Run("responsibility_chain_6000: ", ChainOfResponsibility6000)
}

// ChainOfResponsibility200 200元报销请求
func ChainOfResponsibility200(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandler(leader)
 handlerChain.AddHandler(director)
 handlerChain.AddHandler(cfo)

 request := Request{
  Name:   "kay",
  Amount: 200,
 }
 handlerChain.HandleRequest(request)
}

// ChainOfResponsibility3000 3000元报销请求
func ChainOfResponsibility3000(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandlers(leader, director, cfo)

 request := Request{
  Name:   "kay",
  Amount: 3000,
 }
 handlerChain.HandleRequest(request)
}

// ChainOfResponsibility6000 6000元报销请求
func ChainOfResponsibility6000(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandlers(leader, director, cfo)

 request := Request{
  Name:   "kay",
  Amount: 6000,
 }
 handlerChain.HandleRequest(request)
}

19. 策略模式

responsibility_chain.go


/*
    package responsibility_chain 责任链模式,把多个处理器串成链,然后让请求在链上传递。
    以财务审批为例:
    Leader 直接上级只能审核500元以下的报销
 Director 总监只能审核5000元以下的报销
 CFO 首席财务官可以审核任意金额的报销
*/
package responsibility_chain

import "fmt"

// Manager 管理者接口
type Manager interface {
 // Review 审核
 Review(request Request) bool
}

// Request 报销请求
type Request struct {
 // Name 姓名
 Name string
 // Amount 金额
 Amount int
}

// Leader 直接上级只能审核500元以下的报销,实现Manager接口
type Leader struct{}

// Director 总监只能审核5000元以下的报销,实现Manager接口
type Director struct{}

// CFO 首席财务官可以审核任意金额的报销,实现Manager接口
type CFO struct{}

// Review Leader实现报销方法
func (leader Leader) Review(request Request) bool {
 if request.Amount < 500 {
  fmt.Println(fmt.Sprintf("leader 处理了%s的%d元报销", request.Name, request.Amount))
  return true
 }
 return false
}

// Review Director实现报销方法
func (director Director) Review(request Request) bool {
 if request.Amount < 5000 {
  fmt.Println(fmt.Sprintf("director 处理了%s的%d元报销", request.Name, request.Amount))
  return true
 }
 return false
}

// Review CFO实现报销方法
func (cfo CFO) Review(request Request) bool {
 fmt.Println(fmt.Sprintf("cfo 处理了%s的%d元报销", request.Name, request.Amount))
 return true
}

// HandlerChain 责任链处理器
type HandlerChain struct {
 // managers 责任链切片,不可导出
 managers []Manager
}

// AddHandler 责任链处理器对象,添加处理器。注:使用指针接收者,需要更改切片
func (chain *HandlerChain) AddHandler(manager Manager) {
 chain.managers = append(chain.managers, manager)
}

// AddHandlers 责任链处理器对象,批量添加处理器。注:使用指针接收者,需要更改切片
func (chain *HandlerChain) AddHandlers(managers ...Manager) {
 chain.managers = append(chain.managers, managers...)
}

// HandleRequest 责任链处理器对象,处理请求
func (chain *HandlerChain) HandleRequest(request Request) error {
 for _, manager := range chain.managers {
  result := manager.Review(request)
  // 如果result为true,则说明已经处理完成
  if result {
   return nil
  }
 }
 return fmt.Errorf("请求未被处理")
}


responsibility_chain_test.go


package responsibility_chain

import "testing"

func Test(t *testing.T) {
 t.Run("responsibility_chain_200: ", ChainOfResponsibility200)
 t.Run("responsibility_chain_3000: ", ChainOfResponsibility3000)
 t.Run("responsibility_chain_6000: ", ChainOfResponsibility6000)
}

// ChainOfResponsibility200 200元报销请求
func ChainOfResponsibility200(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandler(leader)
 handlerChain.AddHandler(director)
 handlerChain.AddHandler(cfo)

 request := Request{
  Name:   "kay",
  Amount: 200,
 }
 handlerChain.HandleRequest(request)
}

// ChainOfResponsibility3000 3000元报销请求
func ChainOfResponsibility3000(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandlers(leader, director, cfo)

 request := Request{
  Name:   "kay",
  Amount: 3000,
 }
 handlerChain.HandleRequest(request)
}

// ChainOfResponsibility6000 6000元报销请求
func ChainOfResponsibility6000(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandlers(leader, director, cfo)

 request := Request{
  Name:   "kay",
  Amount: 6000,
 }
 handlerChain.HandleRequest(request)
}

20. 模版模式

responsibility_chain.go


/*
    package responsibility_chain 责任链模式,把多个处理器串成链,然后让请求在链上传递。
    以财务审批为例:
    Leader 直接上级只能审核500元以下的报销
 Director 总监只能审核5000元以下的报销
 CFO 首席财务官可以审核任意金额的报销
*/
package responsibility_chain

import "fmt"

// Manager 管理者接口
type Manager interface {
 // Review 审核
 Review(request Request) bool
}

// Request 报销请求
type Request struct {
 // Name 姓名
 Name string
 // Amount 金额
 Amount int
}

// Leader 直接上级只能审核500元以下的报销,实现Manager接口
type Leader struct{}

// Director 总监只能审核5000元以下的报销,实现Manager接口
type Director struct{}

// CFO 首席财务官可以审核任意金额的报销,实现Manager接口
type CFO struct{}

// Review Leader实现报销方法
func (leader Leader) Review(request Request) bool {
 if request.Amount < 500 {
  fmt.Println(fmt.Sprintf("leader 处理了%s的%d元报销", request.Name, request.Amount))
  return true
 }
 return false
}

// Review Director实现报销方法
func (director Director) Review(request Request) bool {
 if request.Amount < 5000 {
  fmt.Println(fmt.Sprintf("director 处理了%s的%d元报销", request.Name, request.Amount))
  return true
 }
 return false
}

// Review CFO实现报销方法
func (cfo CFO) Review(request Request) bool {
 fmt.Println(fmt.Sprintf("cfo 处理了%s的%d元报销", request.Name, request.Amount))
 return true
}

// HandlerChain 责任链处理器
type HandlerChain struct {
 // managers 责任链切片,不可导出
 managers []Manager
}

// AddHandler 责任链处理器对象,添加处理器。注:使用指针接收者,需要更改切片
func (chain *HandlerChain) AddHandler(manager Manager) {
 chain.managers = append(chain.managers, manager)
}

// AddHandlers 责任链处理器对象,批量添加处理器。注:使用指针接收者,需要更改切片
func (chain *HandlerChain) AddHandlers(managers ...Manager) {
 chain.managers = append(chain.managers, managers...)
}

// HandleRequest 责任链处理器对象,处理请求
func (chain *HandlerChain) HandleRequest(request Request) error {
 for _, manager := range chain.managers {
  result := manager.Review(request)
  // 如果result为true,则说明已经处理完成
  if result {
   return nil
  }
 }
 return fmt.Errorf("请求未被处理")
}


responsibility_chain_test.go


package responsibility_chain

import "testing"

func Test(t *testing.T) {
 t.Run("responsibility_chain_200: ", ChainOfResponsibility200)
 t.Run("responsibility_chain_3000: ", ChainOfResponsibility3000)
 t.Run("responsibility_chain_6000: ", ChainOfResponsibility6000)
}

// ChainOfResponsibility200 200元报销请求
func ChainOfResponsibility200(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandler(leader)
 handlerChain.AddHandler(director)
 handlerChain.AddHandler(cfo)

 request := Request{
  Name:   "kay",
  Amount: 200,
 }
 handlerChain.HandleRequest(request)
}

// ChainOfResponsibility3000 3000元报销请求
func ChainOfResponsibility3000(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandlers(leader, director, cfo)

 request := Request{
  Name:   "kay",
  Amount: 3000,
 }
 handlerChain.HandleRequest(request)
}

// ChainOfResponsibility6000 6000元报销请求
func ChainOfResponsibility6000(t *testing.T) {
 var leader, director, cfo Manager
 leader = &Leader{}
 director = &Director{}
 cfo = &CFO{}

 handlerChain := HandlerChain{}
 handlerChain.AddHandlers(leader, director, cfo)

 request := Request{
  Name:   "kay",
  Amount: 6000,
 }
 handlerChain.HandleRequest(request)
}
说点什么吧...