什么是责任链模式?
为请求创建了一个接收者对象的链,每个接收者都包含对另一个接收者的引用,当某个接受者不能处理该请求时,会将该请求转给下一个接受者处理;
Go 语言实现:
package chain_of_responsibility
import "strconv"
//责任链模式:为请求创建了一个接受者对象的链,每个接收者都包含对另一个接收者的引用,当某个接收者不能处理该请求时,会将该请求转给下一个接受者处理
type Trouble struct {
number int
}
func (self *Trouble) getNumber() int { // get到私有属性
return self.number
}
type support interface {
resolve(trouble Trouble) bool //留给子类实现
Handle(support support, trouble Trouble) string //相当于模板方法
}
//默认实现,链式结构
type defaultSupport struct {
support //实现support接口
name string
next support
}
func (self *defaultSupport) SetNext(next support) { //设置下一个support
self.next = next
}
//自定义方法
func (self *defaultSupport) done(trouble Trouble) string {
return "trouble:" + strconv.Itoa(trouble.getNumber()) + " is resolved by " + self.name
}
func (self *defaultSupport) fail(trouble Trouble) string {
return "trouble:" + strconv.Itoa(trouble.getNumber()) + " cannot be resolved"
}
//模板方法,链式调用
func (self *defaultSupport) Handle(support support, trouble Trouble) string {
if support.resolve(trouble) {
return self.done(trouble)
} else if self.next != nil {
return self.next.Handle(self.next, trouble)
} else {
return self.fail(trouble)
}
}
//继承父类指针,此时动态拥有父类新增的方法
type noSupport struct {
*defaultSupport
}
func (self *noSupport) resolve(trouble Trouble) bool {
return false
}
func NewNoSupport(name string) *noSupport {
return &noSupport{&defaultSupport{name: name}}
}
//继承父类指针,此时动态拥有父类新增的方法
type limitSupport struct {
*defaultSupport
limit int
}
func (self *limitSupport) resolve(trouble Trouble) bool {
if trouble.getNumber() < self.limit {
return true
} else {
return false
}
}
func NewLimitSupport(name string, limit int) *limitSupport {
return &limitSupport{&defaultSupport{name: name}, limit}
}
package chain_of_responsibility
import "testing"
func TestChainOfResponsibility(t *testing.T) {
a := NewNoSupport("A") //继承自defaultSupport,defaultSupport实现了Handle
b := NewLimitSupport("B", 2)
c := NewLimitSupport("C", 3)
a.SetNext(b)
b.SetNext(c)
result := a.Handle(a, Trouble{1})
expect := "trouble:1 is resolved by B"
if result != expect {
t.Errorf("Expect result to be equal %s,but %s\n", expect, result)
}
result = a.Handle(a, Trouble{2})
expect = "trouble:2 is resolved by C"
if result != expect {
t.Errorf("Expect result to be equal %s,but %s\n", expect, result)
}
result = a.Handle(a, Trouble{3})
expect = "trouble:3 cannot be resolved"
if result != expect {
t.Errorf("Expect result to be equal %s ,but %s\n", expect, result)
}
}