14、 Golang 设计模式:14_责任链模式

1、原理

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

责任链模式(Chain of Responsibility)是一种处理请求的模式,它让多个处理器都有机会处理该请求,直到其中某个处理成功为止。责任链模式把多个处理器串成链,然后让请求在链上传递:

     ┌─────────┐
     │ Request │
     └─────────┘
          │
┌ ─ ─ ─ ─ ┼ ─ ─ ─ ─ ┐
          ▼
│  ┌─────────────┐  │
   │ ProcessorA  │
│  └─────────────┘  │
          │
│         ▼         │
   ┌─────────────┐
│  │ ProcessorB  │  │
   └─────────────┘
│         │         │
          ▼
│  ┌─────────────┐  │
   │ ProcessorC  │
│  └─────────────┘  │
          │
└ ─ ─ ─ ─ ┼ ─ ─ ─ ─ ┘
          │
          ▼

 

 

2、示例

示例代码:

package main

import "fmt"

type Manager interface {
	HaveRight(money int)bool //有权做
	HandleFeeRequest(name string,money int)bool //处理费用请求
}
type RequestChain struct {
	Manager
	successor *RequestChain //后续者(链式结构,链表)
}

func (rc *RequestChain)HaveRight(money int)bool {
	return true
}
func (rc *RequestChain)HandleFeeRequest(name string,money int)bool {
	//先判断金额在对应的部门是否有权限
	if rc.Manager.HaveRight(money) {
		return rc.Manager.HandleFeeRequest(name,money) //如果有权限,处理请求
	}
	//继任者不为空,传递到继任者处理
	if rc.successor!=nil {
		return rc.successor.HandleFeeRequest(name,money)
	}
	return false
}
//赋值下一个继任者
func (rc *RequestChain)SetSuccessor(m *RequestChain) {
	rc.successor=m
}

type ProjectManage struct {}

func (pm *ProjectManage)HaveRight(money int)bool {
	return  money<500
}
func (pm *ProjectManage)HandleFeeRequest(name string,money int)bool {
	if name=="海淀区" {
		fmt.Printf("工程管理拥有权限,%v:%v\n",name,money)
		return true
	}
	fmt.Printf("工程管理没有权限,%v:%v\n",name,money)
	return false
}
func NewProjectManage() *RequestChain {
	return &RequestChain{
		Manager:   &ProjectManage{},
		successor: nil,
	}
}

type DepManager struct {}

func (dm *DepManager)HaveRight(money int)bool  {
	return money<5000
}
func (dm *DepManager)HandleFeeRequest(name string,money int)bool  {
	if name=="北京市" {
		fmt.Printf("部门管理授权通过,%v:%v\n",name,money)
		return true
	}
	fmt.Printf("部门管理未授权,%v:%v\n",name,money)
	return false
}
func NewDepManager() *RequestChain {
	return &RequestChain{
		Manager:   &DepManager{},
		successor: nil,
	}
}
type GeneralManager struct {}
func (gm *GeneralManager)HaveRight(money int)bool  {
	return true
}
func (gm *GeneralManager)HandleFeeRequest(name string,money int)bool  {
	if name=="中央" {
		fmt.Printf("全体管理授权通过,%v:%v\n",name,money)
		return true
	}
	fmt.Printf("全体管理未授权,%v:%v\n",name,money)
	return false
}
func NewGeneralManager() *RequestChain {
	return &RequestChain{
		Manager:   &GeneralManager{},
		successor: nil,
	}
}
func main() {
	c1:=NewProjectManage()
	c2:=NewDepManager()
	c3:=NewGeneralManager()
	//责任传递方向: c1---->c2----->c3
	c1.SetSuccessor(c2)
	c2.SetSuccessor(c3)

	var c Manager=c1
	c.HandleFeeRequest("海淀区",400)
	c.HandleFeeRequest("北京市",1400)
	c.HandleFeeRequest("中央",10000)
	c.HandleFeeRequest("天津市",400)
}

UML图: