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())
//切片变了,要重新获取
//切片变了,所以要重新获取快照.
//如果想进一步了解看以这个例子:
//https://github.com/crazybber/go-fucking-exercise/blob/master/routine/slice_read_write_test.go
potInterator = scenicArea.Iterator()
potInterator.Reset()

View File

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

View File

@ -2,93 +2,148 @@ package chain
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 {
Manager
successor *RequestChain
//IApprove 审批动作
type IApprove interface {
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 {
if r.Manager.HaveRight(money) {
return r.Manager.HandleFeeRequest(name, money)
//AddApprover 添加一个审批对象
func (f *FeeRequestChainFlow) AddApprover(approver IApprove) {
f.approvers = append(f.approvers, approver)
}
//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
}
}
if r.successor != nil {
return r.successor.HandleFeeRequest(name, money)
}
return false
}
func (r *RequestChain) HaveRight(money int) bool {
////////////////////////////////
//实现方式2
////////////////////////////////
//GM 总经理要审批
type GM struct {
nextHandler IApprove //下一个流程节点
level int
}
//NewGM 总经理审批
func NewGM() IApprove {
return &GM{level: 8}
}
//SetNext 设置下一个审批节点
func (g *GM) SetNext(next IApprove) {
g.nextHandler = next
}
//HaveRight 处理审批所需要的权限级别
func (g *GM) HaveRight(level int) bool {
return g.level > level
}
//HandleApproval 进行审批
func (g *GM) HandleApproval(request FeeRequest) bool {
if g.HaveRight(request.RequiredLevel) {
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)
//direct forward to Next One
if g.nextHandler != nil {
return g.nextHandler.HandleApproval(request)
}
return true
}
type ProjectManager struct{}
func NewProjectManagerChain() *RequestChain {
return &RequestChain{
Manager: &ProjectManager{},
}
//CFO 需要审批
type CFO struct {
nextHandler IApprove //下一个流程节点
level int
}
func (*ProjectManager) HaveRight(money int) bool {
return money < 500
//NewCFO 对象
func NewCFO() IApprove {
return &CFO{}
}
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 {
//HaveRight CFO总是有权限的
func (*CFO) HaveRight(RequiredLevel 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)
//SetNext 设置下一个审批节点
func (c *CFO) SetNext(next IApprove) {
c.nextHandler = next
}
//HandleApproval 进行审批
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("General manager don't permit %s %d fee request\n", name, money)
// 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
}

View File

@ -1,23 +1,39 @@
package chain
func ExampleChain() {
c1 := NewProjectManagerChain()
c2 := NewDepManagerChain()
c3 := NewGeneralManagerChain()
import "testing"
c1.SetSuccessor(c2)
c2.SetSuccessor(c3)
func TestChainsOfResponsibilityInApprovementList(t *testing.T) {
var c Manager = c1
request := FeeRequest{
Name: "sophia",
Mount: 1e+13,
RequiredLevel: 8,
}
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
flow := &FeeRequestChainFlow{}
gm1 := &GM{level: 7}
cfo1 := &CFO{level: 9}
flow.AddApprover(gm1)
flow.AddApprover(cfo1)
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) {
}