您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“Chain of Responsibility職責鏈模式怎么實現”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Chain of Responsibility職責鏈模式怎么實現”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
Chain of Responsibility(職責鏈模式)
Chain of Responsibility(職責鏈模式)屬于行為型模式。行為型模式不僅描述對象或類的模式,還描述它們之間的通信模式,比如對操作的處理應該如何傳遞等等。
意圖:使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關系。將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理它為止。
幾乎所有設計模式,在了解到它之前,筆者就已經在實戰中遇到過了,因此設計模式的確是從實踐中得出的真知。但另一方面,如果沒有實戰的理解,單看設計模式是枯燥的,而且難以理解的,因此大家學習設計模式時,要結合實際問題思考。
舉例子
如果看不懂上面的意圖介紹,沒有關系,設計模式需要在日常工作里用起來,結合例子可以加深你的理解,下面我準備了三個例子,讓你體會什么場景下會用到這種設計模式。
中間件機制
設想我們要為一個后端框架實現中間件(知道 Koa 的同學可以理解為 Koa 的洋蔥模型),在代碼中可以插入任意多個中間件,每個中間件都可以對請求與響應進行處理。
由于每個中間件只響應自己感興趣的請求,因此只有運行時才知道這個中間件是否會處理請求,那么中間件機制應該如何設計,才能保證其功能和靈活性呢?
通用幫助文案
如果一個大型系統中,任何一個模塊點擊都會彈出幫助文案,但并不是每個模塊都有幫助文案的,如果一個模塊沒有幫助文案,則顯示其父級的幫助文案,如果再沒有,就繼續冒泡到整個應用,展示應用級別的兜底幫助文案。這種系統應該如何設計?
JS 事件冒泡機制
其實 JS 事件冒泡機制就是個典型的職責鏈模式,因為任何 DOM 元素都可以監聽比如 onClick,不僅可以自己響應事件,還可以使用 event.stopPropagation() 阻止繼續冒泡。
意圖解釋
JS 事件冒泡機制對前端來說太常見了,但我們換個角度,站在點擊事件的角度理解,就能重新發現其設計的精妙之處:
點擊事件是疊加在每層 dom 上的,由于 dom 對事件的處理和綁定是動態的,瀏覽器本身不知道哪些地方會處理點擊事件,但又要讓每層 dom 擁有對點擊事件的 “平等處理權”,所以就產生了冒泡機制,與事件阻止冒泡功能。
通用幫助文案和 JS 事件冒泡很類似,只是把點擊事件換成了彈出幫助文案罷了,其場景機理是一樣的。
說到這,我們可以再重新理解一下職責鏈模式的意圖:
意圖:使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關系。將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理它為止。
請求指的是某個觸發機制產生的請求,是一個通用概念。“避免請求的發送者和接收者之間的耦合關系”,指的是如果我們只有一個對象有處理請求的機會,那接收者就與發送者之間耦合了,其他接收者必須通過這個接收者才能繼續處理,這種模式不夠靈活。
后半句描述的是如何設計,可以實現這個靈活的模式,即將對象連成一條鏈,沿著鏈條傳遞該請求,直到有一個對象處理它為止。還要理解到,任何一個對象都擁有阻斷請求繼續傳遞的能力。
在中間件機制的例子中,后端 Web 框架對 Http 請求的處理就是個運用職責鏈模式的典型案例,因為后端框架要處理的請求是平行關系,任何請求都可能要求被響應,但對請求的處理是通過插件機制拓展的,且對每個請求的處理都是一個鏈條,存在處理、加工、再處理的邏輯關系。
結構圖
Handler 就是對請求的處理,可以看到這里是一條環路,只要處理完之后就可以交給下一個 Handler 進行處理,可以在中途攔截后中斷,也可以穿透整條鏈路。
ConcreteHandler 是具體 Handler 的實現,他們都需要繼承 Handler 以具備相同的 HandleRequest 方法,這樣每一個處理中間件就都擁有了處理能力,使得這些對象連成的鏈條可以對請求進行傳遞。
代碼例子
職責鏈實現方式非常多,比如 Koa 的洋蔥模型實現原理就值得再寫一篇文章,感興趣的同學可以閱讀 co 源碼。這里僅介紹最簡單場景的實現方案。
職責鏈的簡單實現模式也分為兩種,一種是每個對象本身維護到下一個對象的引用,另一種是由 Handler 維護后繼者。
下面例子使用 typescript 編寫。
public class Handler {
private nextHandler: Handler
public handle() {
if(nextHandler) {
nextHandler.handle()
}
}
}
每個 Handler 的默認行為就是觸發下一個鏈條的 handle,因此什么都不做的話,這個鏈條是完全打通的,因此我們可以在鏈條的任何一環進行處理。
處理的方式就是重寫 handle 函數,我們在重寫時,可以維持對 nextHandler.handle() 的調用,以使得鏈條繼續向后傳遞,也可以不調用,從而終止鏈條向后傳遞。
弊端
職責鏈模式不保證每個中間件都有機會處理請求,因為中間件順序的問題,后面中間件可能被前面的中間件阻斷,因此當中間件之間存在不信任關系時,職責鏈模式并不能保證中間件調用的可靠性。
另外就是不要擴大設計模式的使用范圍,對一堆對象的連續調用就沒必要使用職責鏈模式,因為職責鏈適合處理對象數量不確定、是否處理請求由每個對象靈活決定的場景,而確定了對象數量以及是否調用的場景,就沒必要使用職責鏈模式了。
讀到這里,這篇“Chain of Responsibility職責鏈模式怎么實現”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。