[设计模式 Go实现] 行为型~职责链模式

职责链模式

职责链模式用于分离不同职责,并且动态组合相关职责。

Golang实现职责链模式时候,因为没有继承的支持,使用链对象包涵职责的方式,即:

  • 链对象包含当前职责对象以及下一个职责链。
  • 职责对象提供接口表示是否能处理对应请求。
  • 职责对象提供处理函数处理相关职责。

同时可在职责链类中实现职责接口相关函数,使职责链对象可以当做一般职责对象是用。

chain.go
go 复制代码
package chain

import "fmt"

type Manager interface {
    HaveRight(money int) bool
    HandleFeeRequest(name string, money int) bool
}

type RequestChain struct {
    Manager
    successor *RequestChain
}

func (r *RequestChain) SetSuccessor(m *RequestChain) {
    r.successor = m
}

func (r *RequestChain) HandleFeeRequest(name string, money int) bool {
    if r.Manager.HaveRight(money) {
        return r.Manager.HandleFeeRequest(name, money)
    }
    if r.successor != nil {
        return r.successor.HandleFeeRequest(name, money)
    }
    return false
}

func (r *RequestChain) HaveRight(money int) bool {
    return true
}

type ProjectManager struct{}

func NewProjectManagerChain() *RequestChain {
    return &RequestChain{
        Manager: &ProjectManager{},
    }
}

func (*ProjectManager) HaveRight(money int) bool {
    return money < 500
}

func (*ProjectManager) HandleFeeRequest(name string, money int) bool {
    if name == "bob" {
        fmt.Printf("Project manager permit %s %d fee request\n", name, money)
        return true
    }
    fmt.Printf("Project manager don't permit %s %d fee request\n", name, money)
    return false
}

type DepManager struct{}

func NewDepManagerChain() *RequestChain {
    return &RequestChain{
        Manager: &DepManager{},
    }
}

func (*DepManager) HaveRight(money int) bool {
    return money < 5000
}

func (*DepManager) HandleFeeRequest(name string, money int) bool {
    if name == "tom" {
        fmt.Printf("Dep manager permit %s %d fee request\n", name, money)
        return true
    }
    fmt.Printf("Dep manager don't permit %s %d fee request\n", name, money)
    return false
}

type GeneralManager struct{}

func NewGeneralManagerChain() *RequestChain {
    return &RequestChain{
        Manager: &GeneralManager{},
    }
}

func (*GeneralManager) HaveRight(money int) bool {
    return true
}

func (*GeneralManager) HandleFeeRequest(name string, money int) bool {
    if name == "ada" {
        fmt.Printf("General manager permit %s %d fee request\n", name, money)
        return true
    }
    fmt.Printf("General manager don't permit %s %d fee request\n", name, money)
    return false
}
chain_test.go
go 复制代码
package chain

func ExampleChain() {
    c1 := NewProjectManagerChain()
    c2 := NewDepManagerChain()
    c3 := NewGeneralManagerChain()

    c1.SetSuccessor(c2)
    c2.SetSuccessor(c3)

    var c Manager = c1

    c.HandleFeeRequest("bob", 400)
    c.HandleFeeRequest("tom", 1400)
    c.HandleFeeRequest("ada", 10000)
    c.HandleFeeRequest("floar", 400)
    // Output:
    // Project manager permit bob 400 fee request
    // Dep manager permit tom 1400 fee request
    // General manager permit ada 10000 fee request
    // Project manager don't permit floar 400 fee request

}
相关推荐
kyriewen4 分钟前
代码写成一锅粥?3个设计模式让你的项目“起死回生”
前端·javascript·设计模式
Pkmer9 小时前
古法编程: 适配器模式
java·设计模式
研究点啥好呢11 小时前
滴滴Go后端开发工程师面试题精选:10道高频考题+答案解析
java·开发语言·golang
NEGl DRYN12 小时前
Go基础之环境搭建
开发语言·后端·golang
初心未改HD12 小时前
Go Modules:依赖管理的完全指南
开发语言·golang
rOuN STAT12 小时前
Golang 构建学习
开发语言·学习·golang
不甘先生13 小时前
Go context 实战指南:从入门到生产级并发控制(架构师避坑手册)
开发语言·后端·golang
初心未改HD13 小时前
Go 泛型完全指南:从入门到实战
开发语言·golang
止语Lab1 天前
从手动到框架:Go DI 演进的三个拐点
开发语言·后端·golang
灰子学技术1 天前
Envoy 使用的设计模式技术文档
设计模式