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)
}
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)
}
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)
}