add code to chain_of_responsibility pattern

This commit is contained in:
Edward 2020-05-04 01:11:19 +08:00
parent 1e31d93f60
commit d08b2bd23c
4 changed files with 160 additions and 92 deletions

View File

@ -35,7 +35,9 @@ func TestIterator(t *testing.T) {
t.Log("pots count:", scenicArea.PotsCount()) t.Log("pots count:", scenicArea.PotsCount())
//切片变了,要重新获取 //切片变了,所以要重新获取快照.
//如果想进一步了解看以这个例子:
//https://github.com/crazybber/go-fucking-exercise/blob/master/routine/slice_read_write_test.go
potInterator = scenicArea.Iterator() potInterator = scenicArea.Iterator()
potInterator.Reset() potInterator.Reset()

View File

@ -3,13 +3,8 @@
职责链模式用于动态组合一些行为在go实现相对更为简单行为模式中提到的option模式跟此模式很像但是两者场景用例不同op模式的行为常常用于对象初始化或者某一过程中设置参数职责链主要作用在于动态组合行为链以便处理特定的对象或者问题。 职责链模式用于动态组合一些行为在go实现相对更为简单行为模式中提到的option模式跟此模式很像但是两者场景用例不同op模式的行为常常用于对象初始化或者某一过程中设置参数职责链主要作用在于动态组合行为链以便处理特定的对象或者问题。
中间件模式就是一个典型的职责链模式,一个对象,在中间件中层层传递,每一层都可以进行自己的处理。 各大框架和语言中间件模式就是一个典型的职责链模式,一个对象,在中间件中层层传递,每一层都可以进行自己的处理。
Golang中由于函数对象存在使得职责链模式实现来更加灵活。
Golang实现职责链模式时候因为没有继承的支持使用链对象包涵职责的方式 现实生活中的一个申请的行政审批流程就是一个很好的职责链的例子,一个申请提交之后,要经过若干人对其进行处理。
* 链对象包含当前职责对象以及下一个职责链。
* 职责对象提供接口表示是否能处理对应请求。
* 职责对象提供处理函数处理相关职责。
同时可在职责链类中实现职责接口相关函数,使职责链对象可以当做一般职责对象是用。

View File

@ -2,93 +2,148 @@ package chain
import "fmt" import "fmt"
type Manager interface { ////////////////////////////////
HaveRight(money int) bool //使用费用申请审批的例子
HandleFeeRequest(name string, money int) bool
//FeeRequest 这就要要处理的对象
type FeeRequest struct {
Mount int //申请的金额
RequiredLevel int //审批人等级要求
Name string //申请人
} }
type RequestChain struct { //IApprove 审批动作
Manager type IApprove interface {
successor *RequestChain SetNext(next IApprove) //设置下一个审批流转
HaveRight(level int) bool //
HandleApproval(request FeeRequest) bool
} }
func (r *RequestChain) SetSuccessor(m *RequestChain) { ////////////////////////////////
r.successor = m //实现方式1
////////////////////////////////
//FeeRequestChainFlow 定义一个流程管理器
type FeeRequestChainFlow struct {
approvers []IApprove //下一个流程节点
} }
func (r *RequestChain) HandleFeeRequest(name string, money int) bool { //AddApprover 添加一个审批对象
if r.Manager.HaveRight(money) { func (f *FeeRequestChainFlow) AddApprover(approver IApprove) {
return r.Manager.HandleFeeRequest(name, money) f.approvers = append(f.approvers, approver)
} }
if r.successor != nil {
return r.successor.HandleFeeRequest(name, money) //RunApprovalFlow to deal request by chains
func (f *FeeRequestChainFlow) RunApprovalFlow(request FeeRequest) {
for i := 0; i < len(f.approvers); i++ {
result := f.approvers[i].HandleApproval(request)
if !result {
//中间有一个环节出问题,流程就终止
break
} }
return false }
}
}
func (r *RequestChain) HaveRight(money int) bool {
return true ////////////////////////////////
} //实现方式2
////////////////////////////////
type ProjectManager struct{}
//GM 总经理要审批
func NewProjectManagerChain() *RequestChain { type GM struct {
return &RequestChain{ nextHandler IApprove //下一个流程节点
Manager: &ProjectManager{}, level int
} }
}
//NewGM 总经理审批
func (*ProjectManager) HaveRight(money int) bool { func NewGM() IApprove {
return money < 500 return &GM{level: 8}
} }
func (*ProjectManager) HandleFeeRequest(name string, money int) bool { //SetNext 设置下一个审批节点
if name == "bob" { func (g *GM) SetNext(next IApprove) {
fmt.Printf("Project manager permit %s %d fee request\n", name, money) g.nextHandler = next
return true }
}
fmt.Printf("Project manager don't permit %s %d fee request\n", name, money) //HaveRight 处理审批所需要的权限级别
return false func (g *GM) HaveRight(level int) bool {
} return g.level > level
}
type DepManager struct{}
//HandleApproval 进行审批
func NewDepManagerChain() *RequestChain { func (g *GM) HandleApproval(request FeeRequest) bool {
return &RequestChain{ if g.HaveRight(request.RequiredLevel) {
Manager: &DepManager{}, fmt.Printf("GM permit %s %d fee request\n", request.Name, request.Mount)
} return true
} }
fmt.Printf("GM Have right to approve %s %d fee request\n", request.Name, request.Mount)
func (*DepManager) HaveRight(money int) bool { //direct forward to Next One
return money < 5000 if g.nextHandler != nil {
} return g.nextHandler.HandleApproval(request)
}
func (*DepManager) HandleFeeRequest(name string, money int) bool { return true
if name == "tom" { }
fmt.Printf("Dep manager permit %s %d fee request\n", name, money)
return true //CFO 需要审批
} type CFO struct {
fmt.Printf("Dep manager don't permit %s %d fee request\n", name, money) nextHandler IApprove //下一个流程节点
return false level int
} }
type GeneralManager struct{} //NewCFO 对象
func NewCFO() IApprove {
func NewGeneralManagerChain() *RequestChain { return &CFO{}
return &RequestChain{
Manager: &GeneralManager{}, }
}
} //HaveRight CFO总是有权限的
func (*CFO) HaveRight(RequiredLevel int) bool {
func (*GeneralManager) HaveRight(money int) bool { return true
return true }
}
//SetNext 设置下一个审批节点
func (*GeneralManager) HandleFeeRequest(name string, money int) bool { func (c *CFO) SetNext(next IApprove) {
if name == "ada" { c.nextHandler = next
fmt.Printf("General manager permit %s %d fee request\n", name, money) }
return true
} //HandleApproval 进行审批
fmt.Printf("General manager don't permit %s %d fee request\n", name, money) func (c *CFO) HandleApproval(request FeeRequest) bool {
if request.Mount < 1e+10 {
fmt.Printf("CFO permit %s %d fee request\n", request.Name, request.Mount)
return true
}
// fmt.Printf("CFO permit %s %d fee request,But still need CEO \n", request.Name, request.Mount)
if c.nextHandler != nil {
return c.nextHandler.HandleApproval(request)
}
return true
}
//CEO 需要审批
type CEO struct{}
//NewCEO 对象
func NewCEO() IApprove {
return &CEO{}
}
//HaveRight CEO总是有权限的
func (*CEO) HaveRight(RequiredLevel int) bool {
return true
}
//SetNext 设置下一个审批节点
func (c *CEO) SetNext(next IApprove) {
//no thing to do
}
//HandleApproval 进行审批
func (*CEO) HandleApproval(request FeeRequest) bool {
if request.Mount < 1e+15 {
fmt.Printf("CEO permit %s %d fee request\n", request.Name, request.Mount)
return true
}
fmt.Printf("CEO deny %s %d fee request \n", request.Name, request.Mount)
return false return false
} }

View File

@ -1,23 +1,39 @@
package chain package chain
func ExampleChain() { import "testing"
c1 := NewProjectManagerChain()
c2 := NewDepManagerChain()
c3 := NewGeneralManagerChain()
c1.SetSuccessor(c2) func TestChainsOfResponsibilityInApprovementList(t *testing.T) {
c2.SetSuccessor(c3)
var c Manager = c1 request := FeeRequest{
Name: "sophia",
Mount: 1e+13,
RequiredLevel: 8,
}
c.HandleFeeRequest("bob", 400) flow := &FeeRequestChainFlow{}
c.HandleFeeRequest("tom", 1400)
c.HandleFeeRequest("ada", 10000) gm1 := &GM{level: 7}
c.HandleFeeRequest("floar", 400)
// Output: cfo1 := &CFO{level: 9}
// Project manager permit bob 400 fee request
// Dep manager permit tom 1400 fee request flow.AddApprover(gm1)
// General manager permit ada 10000 fee request flow.AddApprover(cfo1)
// Project manager don't permit floar 400 fee request
flow.RunApprovalFlow(request)
// request = FeeRequest{
// Name: "peter",
// Mount: 1e+13,
// RequiredLevel: 8,
// }
// ceo := &CEO{level: 10}
// flow.AddApprover(ceo)
// flow.RunApprovalFlow(request)
}
func TestChainsOfResponsibilityInApprovementLink(t *testing.T) {
} }