概念
責(zé)任鏈模式(Chain of Responsibility Pattern):
為了避免請(qǐng)求發(fā)送者與多個(gè)請(qǐng)求處理者耦合在一起塞绿,將所有請(qǐng)求的處理者通過前一對(duì)象記住其下一個(gè)對(duì)象的引用而連成一條鏈废岂;當(dāng)有請(qǐng)求發(fā)生時(shí)蹬挺,可將請(qǐng)求沿著這條鏈傳遞,直到有對(duì)象處理它為止。
責(zé)任鏈模式的本質(zhì)是解耦請(qǐng)求與處理剩盒,讓請(qǐng)求在處理鏈中能進(jìn)行傳遞與被處理;理解責(zé)任鏈模式應(yīng)當(dāng)理解其模式台夺,而不是其具體實(shí)現(xiàn)径玖。責(zé)任鏈模式的獨(dú)到之處是將其節(jié)點(diǎn)處理者組合成了鏈?zhǔn)浇Y(jié)構(gòu),并允許節(jié)點(diǎn)自身決定是否進(jìn)行請(qǐng)求處理或轉(zhuǎn)發(fā)颤介,相當(dāng)于讓請(qǐng)求流動(dòng)起來梳星。
具體實(shí)現(xiàn)
- 抽象處理者(Handler)角色:定義一個(gè)處理請(qǐng)求的接口,包含抽象處理方法和一個(gè)后繼連接滚朵。
- 具體處理者(Concrete Handler)角色:實(shí)現(xiàn)抽象處理者的處理方法冤灾,判斷能否處理本次請(qǐng)求,如果可以處理請(qǐng)求則處理辕近,否則將該請(qǐng)求轉(zhuǎn)給它的后繼者韵吨。
- 客戶類(Client)角色:創(chuàng)建處理鏈,并向鏈頭的具體處理者對(duì)象提交請(qǐng)求移宅,它不關(guān)心處理細(xì)節(jié)和請(qǐng)求的傳遞過程归粉。
chain.jpg
模式的場(chǎng)景和優(yōu)缺點(diǎn)
使用場(chǎng)景
在處理消息的時(shí)候以過濾很多道
優(yōu)點(diǎn)
- 降低耦合度。它將請(qǐng)求的發(fā)送者和接收者解耦
- 簡(jiǎn)化了對(duì)象漏峰。使得對(duì)象不需要知道鏈的結(jié)構(gòu)
- 增強(qiáng)給對(duì)象指派職責(zé)的靈活性
- 通過改變鏈內(nèi)的成員或者調(diào)動(dòng)它們的次序糠悼,允許動(dòng)態(tài)地新增或者刪除責(zé)任
- 增加新的請(qǐng)求處理類很方便
缺點(diǎn)
- 不能保證請(qǐng)求一定被接收
- 系統(tǒng)性能將受到一定影響,而且在進(jìn)行代碼調(diào)試時(shí)不太方便浅乔,可能會(huì)造成循環(huán)調(diào)用
- 可能不容易觀察運(yùn)行時(shí)的特征倔喂,有礙于除錯(cuò)
代碼實(shí)現(xiàn)
package main
import (
"fmt"
)
// Manager 定義接口
type Manager interface {
HaveRight(money int) bool
HandleFeeRequest(name string, money int) bool
}
// ******RequestChain 職責(zé)鏈, 每一個(gè)責(zé)任鏈都要生成這個(gè)職責(zé)鏈******
// successor 繼承者
type RequestChain struct {
Manager
successor *RequestChain
}
// SetSuccessor 設(shè)置處理者
func (r *RequestChain) SetSuccessor(m *RequestChain) {
r.successor = m
}
// HandleFeeRequest 調(diào)用鏈路會(huì)調(diào)用處理者
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
}
// HaveRight ...
func (r *RequestChain) HaveRight(money int) bool {
return true
}
// ************************end**************************
// **********************項(xiàng)目管理責(zé)任鏈靖苇, 實(shí)現(xiàn)Manager接口********************
// ProjectManager ...
type ProjectManager struct {
Name string
}
// NewProjectManagerChain ...
func NewProjectManagerChain(name string) *RequestChain {
return &RequestChain{
Manager: &ProjectManager{Name: name},
}
}
// HaveRight ...
func (p *ProjectManager) HaveRight(money int) bool {
return money < 500
}
// HandleFeeRequest ...
func (p *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
}
// ************************end**************************
// **********************部門管理責(zé)任鏈席噩, 實(shí)現(xiàn)Manager接口*******************
// DepManager ...
type DepManager struct {
Name string
}
// NewDepManagerChain ...
func NewDepManagerChain(name string) *RequestChain {
return &RequestChain{
Manager: &DepManager{Name: name},
}
}
// HaveRight ...
func (d *DepManager) HaveRight(money int) bool {
return money < 5000
}
// HandleFeeRequest ...
func (d *DepManager) HandleFeeRequest(name string, money int) bool {
fmt.Printf("my name:%s\n", d.Name)
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
}
// ************************end**************************
// **********************通用責(zé)任鏈, 實(shí)現(xiàn)Manager接口*******************
// GeneralManager ...
type GeneralManager struct {
Name string
}
// NewGeneralManagerChain ...
func NewGeneralManagerChain(name string) *RequestChain {
return &RequestChain{
Manager: &GeneralManager{Name: name},
}
}
// HaveRight ...
func (g *GeneralManager) HaveRight(money int) bool {
return true
}
// HandleFeeRequest ...
func (g *GeneralManager) HandleFeeRequest(name string, money int) bool {
fmt.Printf("my name:%s\n", g.Name)
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
}
// ************************end**************************
func main() {
c1 := NewProjectManagerChain("c1")
c2 := NewDepManagerChain("c2")
c3 := NewGeneralManagerChain("c3")
//c1 ---> c2 ----> c3
// 設(shè)置下一級(jí)職責(zé)鏈
c1.SetSuccessor(c2)
c2.SetSuccessor(c3)
var c Manager = c1
// RequestChain實(shí)現(xiàn)了Manager
// 以下的調(diào)用全部先調(diào)用RequestChain結(jié)構(gòu)體的HandleFeeRequest函數(shù)
// 然后根據(jù)錢數(shù)顾复, 依次往下調(diào)用班挖。 projectManager -> depManager -> generalManager, 每一級(jí)調(diào)用前芯砸, 先調(diào)用RequestChain結(jié)構(gòu)體的HandleFeeRequest函數(shù)
c.HandleFeeRequest("bob", 400)
c.HandleFeeRequest("tom", 1400)
c.HandleFeeRequest("ada", 10000)
c.HandleFeeRequest("floar", 400)
}