[设计模式 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

}
相关推荐
你采不起的野花40 分钟前
Go 语言 vs C+Lua(Skynet)游戏服务器方案对比分析
游戏·golang·lua
程序员爱钓鱼2 小时前
defer关键字:延迟调用机制-《Go语言实战指南》
开发语言·后端·golang
wktomo2 小时前
GO语言学习(五)
学习·golang·web3
免檒2 小时前
Go内存管理
开发语言·网络·golang·操作系统
飞川撸码2 小时前
【LeetCode 热题100】17:电话号码的字母组合(详细解析)(Go语言版)
算法·leetcode·golang·dfs
CodeWithMe2 小时前
【Go】从0开始学习Go
开发语言·学习·golang
张帅涛_6662 小时前
golang 安装gin包、创建路由基本总结
开发语言·golang·gin
你怎么知道我是队长4 小时前
GO语言语法---switch语句
golang
fashia5 小时前
Java转Go日记(三十九):Gorm查询
开发语言·后端·golang·go
无奇不有 不置可否5 小时前
Java中的设计模式
java·开发语言·设计模式