職責鏈將處理模組串聯成鏈,請求沿著鏈條被處理,提供了很好的擴充套件性,而且能夠去掉if-else。
UML類圖位置:https://www。processon。com/view/link/60d29bf3e401fd49502afd25
本文程式碼連結為:
https://github。com/shidawuhen/asap/blob/master/controller/design/21chain。go
1。定義
1。1職責鏈模式
職責鏈模式
(Chain of Responsibility):使多個物件都有機會處理請求,從而避免請求的傳送者和接收者之間的耦合關係。將這個物件連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個物件處理它為止。
UML
:
1。2分析
職責鏈模式的定義已經將模式說的比較清楚了,一個請求需要被多個物件進行處理,可以將處理物件連成一條鏈,挨個處理請求。
連成鏈的方式比較多樣,可以用UML中展示的那樣,一個處理物件使用SetSuccessor引用下一個處理物件。也可以使用array或者list儲存所有處理物件,使用迴圈方式遍歷。
對於第二種方式,是否感覺有些像Go設計模式(18)-觀察者模式。兩者具體實現、目的都差不多,主要區別在觀察者模式中的處理物件功能可能完全不相似,而且觀察者模式主要負責將資訊傳遞給處理物件即可。職責鏈模式的處理物件功能一般相似,另外職責鏈模式也關注請求是否正確被處理。
另外,定義裡說”直到有一個物件處理它“也不太準確,有多少物件可以處理請求看具體需求,極端情況下每一個物件都可以處理請求。
職責鏈模式的核心在於將處理物件整理成鏈路。
2。應用場景
如果請求被多個物件進行處理,就可以用職責鏈模式。具體業務的像敏感詞脫敏,框架中的過濾器、攔截器等。
總體感覺框架中使用的比較多一些,研發人員能夠
快速擴展出自己的過濾器和攔截器
。
以前寫過Gin原始碼剖析,裡面有全域性中介軟體的概念,而全域性中介軟體使用的便是職責鏈模式。
3。程式碼實現
我們仿照Gin,實現Gin的全域性中介軟體功能。
package mainimport “fmt”var status int8 = 0type HandlerFunc func()type HandlersChain []HandlerFunc/** * @Author: Jason Pang * @Description: */type RouterGroup struct { Handlers HandlersChain index int8}/** * @Author: Jason Pang * @Description: 新增中介軟體,將其組成鏈式 * @receiver group * @param middleware */func (group *RouterGroup) Use(middleware 。。。HandlerFunc) { group。Handlers = append(group。Handlers, middleware。。。)}/** * @Author: Jason Pang * @Description: 鏈順序執行 * @receiver group */func (group *RouterGroup) Next() { for group。index < int8(len(group。Handlers)) { group。Handlers[group。index]() group。index++ }}/** * @Author: Jason Pang * @Description: 中介軟體 */func middleware1() { fmt。Println(“全域性中介軟體1執行完畢”)}/** * @Author: Jason Pang * @Description: 中介軟體 */func middleware2() { fmt。Println(“全域性中介軟體2執行失敗”) status = 1}func main() { r := &RouterGroup{} //新增中介軟體 r。Use(middleware1, middleware2) //執行中介軟體 r。Next() //狀態檢查 if status == 1 { fmt。Println(“中介軟體檢查失敗,請重試”) return } //執行後續流程}
輸出:
➜ myproject go run main。go
全域性中介軟體1執行完畢
全域性中介軟體2執行失敗
中介軟體檢查失敗,請重試
這是一個簡版的中介軟體執行過程,我將Gin中的Context和RouterGroup合併了。雖然比起真正的執行流程缺乏很多內容,但是核心操作是一致的。
3。總結
透過Gin中介軟體的例子,可以很好證明職責鏈的擴充套件性。簡單
使
用Use增加自己建立的中介軟體,每一個請求都會被新增的中介軟體所處理。所以開發者可以方便的增加鑑權、限流、脫敏、攔截等操作。這就是所謂的優雅吧。
最後
大家如果喜歡我的文章,可以關注我的公眾號(程式設計師麻辣燙)
我的個人部落格為:https://shidawuhen。github。io/
往期文章回顧:
設計模式
招聘
思考
儲存
算法系列
讀書筆記
小工具
架構
網路
Go語言