責任鏈模式會解決這種問題。增加功能時,增加鏈上的處理者即可。不同的維護者維護自己的處理者。
?責任鏈模式的定義:是一種行為型設計模式,請求會沿著處理者鏈進行傳遞。收到請求后,每個處理者均可對請求進行處理,或將其傳遞給鏈的下個處理者。
(資料圖片僅供參考)
在實際工作中,常常會遇到功能擴充,有可能會導致代碼越來越臃腫或邏輯越來越復雜。維護的程序員也可能不止一個,也會導致一些混亂。
責任鏈模式會解決這種問題。增加功能時,增加鏈上的處理者即可。不同的維護者維護自己的處理者。
責任鏈模式滿足單一職責原則,請求和處理者進行了解耦,只要將請求發給一個處理者即可;各個處理者也完成各自的功能。
責任鏈模式滿足開閉原則。可以在不更改現有代碼的情況下在程序中新增處理者。
責任鏈模式中可以控制請求處理的順序。
下面來看代碼實現:
我們來模擬最高指揮部對各個作戰部隊下達指令的情形。請求者就是最高指揮部(HighCommand),處理者有炮兵部隊(Artillery)、導彈部隊(MissileForce)、核部隊(NuclearForce)。各部隊對最高指揮部發出的攻擊指令進行各自的處理。UML圖如下:
interface.go文件:
package maintype Forces interface { Execute(*HighCommand) SetNext(Forces)}
artillery.go文件:
package mainimport "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 mainimport "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 mainimport "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 maintype EndChain struct{}func (f *EndChain) Execute(command *HighCommand) {}func (f *EndChain) SetNext(next Forces) {}
client.go文件:
package maintype HighCommand struct { name string}func (c *HighCommand) ShowCommand() string { return c.name}
main.go文件:
package mainfunc 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)}
運行go run *.go即可。
該例子運行結果為:
最近更新