mirror of
https://github.com/crazybber/go-pattern-examples.git
synced 2024-11-25 21:26:03 +03:00
add code to chain_of_responsibility pattern
This commit is contained in:
parent
1e31d93f60
commit
d08b2bd23c
@ -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()
|
||||||
|
@ -3,13 +3,8 @@
|
|||||||
职责链模式用于动态组合一些行为,在go实现相对更为简单,行为模式中提到的option模式跟此模式很像,但是两者场景用例不同,op模式的行为常常用于对象初始化或者某一过程中设置参数,职责链主要作用在于动态组合行为链,以便处理特定的对象或者问题。
|
职责链模式用于动态组合一些行为,在go实现相对更为简单,行为模式中提到的option模式跟此模式很像,但是两者场景用例不同,op模式的行为常常用于对象初始化或者某一过程中设置参数,职责链主要作用在于动态组合行为链,以便处理特定的对象或者问题。
|
||||||
|
|
||||||
|
|
||||||
中间件模式就是一个典型的职责链模式,一个对象,在中间件中层层传递,每一层都可以进行自己的处理。
|
各大框架和语言中间件模式就是一个典型的职责链模式,一个对象,在中间件中层层传递,每一层都可以进行自己的处理。
|
||||||
|
|
||||||
|
Golang中,由于函数对象存在使得职责链模式实现来更加灵活。
|
||||||
|
|
||||||
Golang实现职责链模式时候,因为没有继承的支持,使用链对象包涵职责的方式,即:
|
现实生活中的一个申请的行政审批流程就是一个很好的职责链的例子,一个申请提交之后,要经过若干人对其进行处理。
|
||||||
|
|
||||||
* 链对象包含当前职责对象以及下一个职责链。
|
|
||||||
* 职责对象提供接口表示是否能处理对应请求。
|
|
||||||
* 职责对象提供处理函数处理相关职责。
|
|
||||||
|
|
||||||
同时可在职责链类中实现职责接口相关函数,使职责链对象可以当做一般职责对象是用。
|
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
|
//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
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProjectManager struct{}
|
//CFO 需要审批
|
||||||
|
type CFO struct {
|
||||||
func NewProjectManagerChain() *RequestChain {
|
nextHandler IApprove //下一个流程节点
|
||||||
return &RequestChain{
|
level int
|
||||||
Manager: &ProjectManager{},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*ProjectManager) HaveRight(money int) bool {
|
//NewCFO 对象
|
||||||
return money < 500
|
func NewCFO() IApprove {
|
||||||
|
return &CFO{}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*ProjectManager) HandleFeeRequest(name string, money int) bool {
|
//HaveRight CFO总是有权限的
|
||||||
if name == "bob" {
|
func (*CFO) HaveRight(RequiredLevel int) bool {
|
||||||
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
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*GeneralManager) HandleFeeRequest(name string, money int) bool {
|
//SetNext 设置下一个审批节点
|
||||||
if name == "ada" {
|
func (c *CFO) SetNext(next IApprove) {
|
||||||
fmt.Printf("General manager permit %s %d fee request\n", name, money)
|
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
|
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
|
return false
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user