?責(zé)任鏈模式的定義:是一種行為型設(shè)計(jì)模式,請(qǐng)求會(huì)沿著處理者鏈進(jìn)行傳遞。收到請(qǐng)求后,每個(gè)處理者均可對(duì)請(qǐng)求進(jìn)行處理,或?qū)⑵鋫鬟f給鏈的下個(gè)處理者。
在實(shí)際工作中,常常會(huì)遇到功能擴(kuò)充,有可能會(huì)導(dǎo)致代碼越來越臃腫或邏輯越來越復(fù)雜。維護(hù)的程序員也可能不止一個(gè),也會(huì)導(dǎo)致一些混亂。
責(zé)任鏈模式會(huì)解決這種問題。增加功能時(shí),增加鏈上的處理者即可。不同的維護(hù)者維護(hù)自己的處理者。
責(zé)任鏈模式滿足單一職責(zé)原則,請(qǐng)求和處理者進(jìn)行了解耦,只要將請(qǐng)求發(fā)給一個(gè)處理者即可;各個(gè)處理者也完成各自的功能。
責(zé)任鏈模式滿足開閉原則??梢栽诓桓默F(xiàn)有代碼的情況下在程序中新增處理者。
責(zé)任鏈模式中可以控制請(qǐng)求處理的順序。
下面來看代碼實(shí)現(xiàn):
我們來模擬最高指揮部對(duì)各個(gè)作戰(zhàn)部隊(duì)下達(dá)指令的情形。請(qǐng)求者就是最高指揮部(HighCommand),處理者有炮兵部隊(duì)(Artillery)、導(dǎo)彈部隊(duì)(MissileForce)、核部隊(duì)(NuclearForce)。各部隊(duì)對(duì)最高指揮部發(fā)出的攻擊指令進(jìn)行各自的處理。UML圖如下:

interface.go文件:
package main
type Forces interface {
Execute(*HighCommand)
SetNext(Forces)
}
artillery.go文件:
package main
import "fmt"
type Artillery struct {
next Forces
}
func (f *Artillery) Execute(command *HighCommand) {
if command.ShowCommand() == "shell attack" {
fmt.Println("Shell Attack!")
return
}
fmt.Println("Send to next")
f.next.Execute(command)
}
func (f *Artillery) SetNext(next Forces) {
f.next = next
}
missileForce.go文件:
package main
import "fmt"
type MissileForce struct {
next Forces
}
func (f *MissileForce) Execute(command *HighCommand) {
if command.ShowCommand() == "missile attack" {
fmt.Println("Missile Attack!")
return
}
fmt.Println("Send to next")
f.next.Execute(command)
}
func (f *MissileForce) SetNext(next Forces) {
f.next = next
}
nuclearForce.go文件:
package main
import "fmt"
type NuclearForce struct {
next Forces
}
func (f *NuclearForce) Execute(command *HighCommand) {
if command.ShowCommand() == "nuclear attack" {
fmt.Println("Nuclear Attack!")
return
}
fmt.Println("Send to next")
f.next.Execute(command)
}
func (f *NuclearForce) SetNext(next Forces) {
f.next = next
}
end.go文件(鏈尾):
package main
type EndChain struct{}
func (f *EndChain) Execute(command *HighCommand) {}
func (f *EndChain) SetNext(next Forces) {}
client.go文件:
package main
type HighCommand struct {
name string
}
func (c *HighCommand) ShowCommand() string {
return c.name
}
main.go文件:
package main
func main() {
// setup chain
end := &EndChain{}
nuclearForce := &NuclearForce{}
nuclearForce.SetNext(end)
missileForce := &MissileForce{}
missileForce.SetNext(nuclearForce)
artillery := &Artillery{}
artillery.SetNext(missileForce)
command := &HighCommand{name: "nuclear attack"}
artillery.Execute(command)
}
運(yùn)行g(shù)o run *.go即可。
該例子運(yùn)行結(jié)果為:
