diff --git a/behavior/06_chain_of_responsibility/README.md b/behavior/06_chain_of_responsibility/README.md new file mode 100644 index 0000000..a137620 --- /dev/null +++ b/behavior/06_chain_of_responsibility/README.md @@ -0,0 +1,15 @@ +# 职责链模式 + +职责链模式用于动态组合一些行为,在go实现相对更为简单,行为模式中提到的option模式跟此模式很像,但是两者场景用例不同,op模式的行为常常用于对象初始化或者某一过程中设置参数,职责链主要作用在于动态组合行为链,以便处理特定的对象或者问题。 + + +中间件模式就是一个典型的职责链模式,一个对象,在中间件中层层传递,每一层都可以进行自己的处理。 + + +Golang实现职责链模式时候,因为没有继承的支持,使用链对象包涵职责的方式,即: + +* 链对象包含当前职责对象以及下一个职责链。 +* 职责对象提供接口表示是否能处理对应请求。 +* 职责对象提供处理函数处理相关职责。 + +同时可在职责链类中实现职责接口相关函数,使职责链对象可以当做一般职责对象是用。 diff --git a/behavior/06_chain_of_responsibility/responsibility_chain.go b/behavior/06_chain_of_responsibility/responsibility_chain.go new file mode 100644 index 0000000..78ecb8a --- /dev/null +++ b/behavior/06_chain_of_responsibility/responsibility_chain.go @@ -0,0 +1,94 @@ +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 +} diff --git a/behavior/06_chain_of_responsibility/responsibility_chain_test.go b/behavior/06_chain_of_responsibility/responsibility_chain_test.go new file mode 100644 index 0000000..b0ddb39 --- /dev/null +++ b/behavior/06_chain_of_responsibility/responsibility_chain_test.go @@ -0,0 +1,23 @@ +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 + +}