1 定义
职责链模式(Chain Of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
现实生活中有很多类似职责链模式的例子,比如我们在公司请假需要填写电子流给各个领导审批,如果请假时长比较短的时候,你的直属领导就有权力决定是否同意你请假,但是如果时间比较长的话,那就要给更高一层的领导审批了,类似的还有加薪申请也是一样的情况。
其UML类图如下:
UML类图:
2 golang实现
2.1 实现各角色
package chainofresponsibility
import "fmt"
type Request struct {
RequestType string
RequestContent string
Number int
}
type Manager interface {
SetNext(next Manager)
RequestHandler(request Request)
}
type CommonManager struct {
Manager
Name string
}
func (cm *CommonManager) SetNext(next Manager) {
cm.Manager = next
}
func (cm *CommonManager) RequestHandler(request Request) {
if request.RequestType == "请假" && request.Number <= 2 {
fmt.Printf("%s: %s 数量 %d 已批准\n", cm.Name, request.RequestContent, request.Number)
} else {
if cm.Manager != nil {
cm.Manager.RequestHandler(request)
}
}
}
type MajorManager struct {
Manager
Name string
}
func (mm *MajorManager) SetNext(next Manager) {
mm.Manager = next
}
func (mm *MajorManager) RequestHandler(request Request) {
if request.RequestType == "请假" && request.Number <= 5 {
fmt.Printf("%s: %s 数量 %d 已批准\n", mm.Name, request.RequestContent, request.Number)
} else {
if mm.Manager != nil {
mm.Manager.RequestHandler(request)
}
}
}
type GeneralManager struct {
Manager
Name string
}
func (gm *GeneralManager) SetNext(next Manager) {
gm.Manager = next
}
func (gm *GeneralManager) RequestHandler(request Request) {
if request.RequestType == "请假" {
fmt.Printf("%s: %s 数量 %d 已批准\n", gm.Name, request.RequestContent, request.Number)
} else if request.RequestType == "加薪" && request.Number <= 500 {
fmt.Printf("%s: %s 数量 %d 已批准\n", gm.Name, request.RequestContent, request.Number)
} else if request.RequestType == "加薪" && request.Number > 500 {
fmt.Printf("%s: %s 数量 %d 再说吧\n", gm.Name, request.RequestContent, request.Number)
}
}
2.2 客户端调用
func main() {
wenxiang := &chainofresponsibility.CommonManager{
Name: "文祥",
}
xiaoyun := &chainofresponsibility.MajorManager{
Name: "晓云",
}
yuanlei := &chainofresponsibility.GeneralManager{
Name: "苑磊",
}
wenxiang.SetNext(xiaoyun)
xiaoyun.SetNext(yuanlei)
request := chainofresponsibility.Request{
RequestType: "请假",
RequestContent: "小菜请假",
Number: 2,
}
wenxiang.RequestHandler(request)
request = chainofresponsibility.Request{
RequestType: "请假",
RequestContent: "小菜请假",
Number: 5,
}
wenxiang.RequestHandler(request)
request = chainofresponsibility.Request{
RequestType: "加薪",
RequestContent: "小菜请求加薪",
Number: 500,
}
wenxiang.RequestHandler(request)
request = chainofresponsibility.Request{
RequestType: "加薪",
RequestContent: "小菜请求加薪",
Number: 1000,
}
wenxiang.RequestHandler(request)
}