Go設計模式(21)-職責鏈模式

職責鏈將處理模組串聯成鏈,請求沿著鏈條被處理,提供了很好的擴充套件性,而且能夠去掉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

Go設計模式(21)-職責鏈模式

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語言