摘要:用實現職責鏈這里使用變量存儲上一個函數,存儲的是最后一個調用返回的函數。理解了過程也就會知道這句代碼是為后面的函數準備的建議如果某塊功能中存在大量的可以考慮使用職責鏈模式
職責鏈模式
1. 職責鏈定義使多個對象都有機會處理請求,從而避免請求的發送者和接受者之間的耦合關系,將對象連成一條鏈,并沿著這個鏈傳遞該請求,直到有一個對象處理它為止
2.職責鏈優點請求發送者只需要知道鏈中的第一個節點,從而弱化了發送者和一組接受者之間的強聯系
3.職責鏈缺點職責鏈模式使得程序中多了一些節點對象,在某次請求傳遞過程中,大部分節點并沒有實質性作用,只是讓請求傳遞下去,從性能方面考慮,要避免過長的職責鏈帶來的性能耗損
4.職責鏈使用場景 4.1 基礎例子商城做活動,預付定金500且購買的客戶可返現100,預付定金200且購買的客戶可返現50,普通購買則沒有返現且庫存不夠買不到。
//設置每個節點的操作,即每種用戶對應的操作,如果不能該節點不能操作則傳遞給下一個節點。 var order500 = function (orderType, pay, stock) { if (orderType === 1 && pay === true) { console.log("100") } else { return "nextSuccessor" } } var order200 = function (orderType, pay, stock) { if (orderType === 2 && pay === true) { console.log("50") } else { return "nextSuccessor" } } var order = function (orderType, pay, stock) { if (stock > 0) { console.log("buy") } else { console.log("lack") } } //職責鏈,規定每個節點的下一個節點,執行本節點的函數 function Chain(fn) { this.fn = fn this.nextSuccessor = null } Chain.prototype.setNextSuccessor = function (successor) { this.nextSuccessor = successor } Chain.prototype.passRequest = function () { var ret = this.fn.apply(this, arguments) if (ret === "nextSuccessor") { return this.nextSuccessor && this.nextSuccessor.passRequest.apply(this.nextSuccessor, arguments) } } //把每個節點都放到職責鏈中 var chainOrder500 = new Chain(order500) var chainOrder200 = new Chain(order200) var chainOrder = new Chain(order) //設置職責鏈的下一個節點 chainOrder500.setNextSuccessor(chainOrder200) chainOrder200.setNextSuccessor(chainOrder) //設定從某個職責鏈節點開始執行 chainOrder500.passRequest(1, true, 1)4.2 異步職責鏈
//設置每個節點的操作,即每種用戶對應的操作,如果不能該節點不能操作則傳遞給下一個節點。 var order500 = function (orderType, pay, stock) { if (orderType === 1 && pay === true) { console.log("100") } else { return "nextSuccessor" } } var order200 = function (orderType, pay, stock) { var self = this setTimeout(function () { self.next() }, 1000) // if (orderType === 2 && pay === true) { // console.log("50") // } else { // return "nextSuccessor" // } } var order = function (orderType, pay, stock) { if (stock > 0) { console.log("buy") } else { console.log("lack") } } //職責鏈,規定每個節點的下一個節點,執行本節點的函數 function Chain(fn) { this.fn = fn this.nextSuccessor = null } Chain.prototype.setNextSuccessor = function (successor) { this.nextSuccessor = successor } Chain.prototype.passRequest = function () { var ret = this.fn.apply(this, arguments) if (ret === "nextSuccessor") { return this.nextSuccessor && this.nextSuccessor.passRequest.apply(this.nextSuccessor, arguments) } } Chain.prototype.next = function () { return (this.nextSuccessor) && this.nextSuccessor.passRequest.apply(this.nextSuccessor, arguments) } // 把每個節點都放到職責鏈中 var chainOrder500 = new Chain(order500) var chainOrder200 = new Chain(order200) var chainOrder = new Chain(order) //設置職責鏈的下一個節點 chainOrder500.setNextSuccessor(chainOrder200) chainOrder200.setNextSuccessor(chainOrder) // 設定從某個職責鏈節點開始執行 chainOrder500.passRequest(1, false, 1)
這里需要增加一個next函數,手動傳遞到下一個節點。
4.3 用AOP實現職責鏈var order500 = function (orderType, pay, stock) { if (orderType === 1 && pay === true) { console.log("100") } else { return "nextSuccessor" } } var order200 = function (orderType, pay, stock) { if (orderType === 2 && pay === true) { console.log("50") } else { return "nextSuccessor" } } var order = function (orderType, pay, stock) { if (stock > 0) { console.log("buy") } else { console.log("lack") } } Function.prototype.after = function (fn) { var self = this return function () { var ret = self.apply(this, arguments) if (ret === "nextSuccessor") { return fn && fn.apply(this, arguments) } return ret } } var func = order500.after(order200).after(order) func(1, true, 3)
這里使用self變量存儲上一個函數,func存儲的是最后一個調用after返回的函數。一旦調用func函數,會先執行self保存的函數,會追根溯源一直到到最開始的self保存的函數order500。這里利用了閉包的特性保留了每一個self變量。整個函數的執行過程有點像倒序的遞歸。理解了過程也就會知道return ret這句代碼是為后面的函數準備的~
5. 建議如果某塊功能中存在大量的if else可以考慮使用職責鏈模式
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97037.html
摘要:提交請求的對象并不明確知道哪一個對象將會處理它也就是該請求有一個隱式的接受者。 20190412期 設計模式-如何理解職責鏈模式? 定義: 使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關系,將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理它為止 也就是說,請求以后,從第一個對象開始,鏈中收到請求的對象要么親自處理它,要么轉發給鏈中的下一個候選者。提...
摘要:使用面向切面編程來快速的創建職責鏈的具體概念可以參考裝飾者模式實現職責鏈簡單又巧妙,但這種把函數疊在一起的方式,同時也疊加了函數的作用域,如果鏈條太長的話,也會對性能造成太大的影響。在開發中,職責鏈模式是最容易被忽視的模式之一。 聲明:這個系列為閱讀《JavaScript設計模式與開發實踐》 ----曾探@著一書的讀書筆記 1.職責鏈模式的定義 2. 2.1 簡單職責鏈模式 2....
摘要:想一想,這個和我們的迭代器模式有著異曲同工的妙處,迭代器模式同樣也是遍歷選出最優解,但是相比而言,職責鏈模式的直觀性個書寫的幸福感是遠遠超過迭代器模式的。 職責鏈模式其實很好理解,由于一個鏈字出賣了它的靈魂。我們可以從這個字得到很大的提示。首先這個模式一定有傳遞性,而且,節點是可以重復拼接的,并且每個節點都具有一定的過濾功能,一定的職責。 是不是想起了組合模式里的一些內容呢? 是的,他...
摘要:簡介職責鏈模式有時候也叫責任鏈模式,它是一種對象行為的設計模式。中的就是使用了責任鏈模式。純的責任鏈模式的實際例子很難找到,一般看到的例子均是不純的責任鏈模式的實現。如果堅持責任鏈不純便不是責任鏈模式,那么責任鏈模式便不會有太大意義了。 Java設計模式之職責鏈模式 前幾天復習java的異常處理時,接觸到了責任鏈模式。在企業級應用中,從前臺發過來的請求在后臺拋出異常,異常處理的設計一般...
摘要:訂閱模式的一個典型的應用就是后面會寫一篇相關的讀書筆記。享元模式享元模式的核心思想是對象復用,減少對象數量,減少內存開銷。適配器模式對目標函數進行數據參數轉化,使其符合目標函數所需要的格式。 設計模式 單例模式 JS的單例模式有別于傳統面向對象語言的單例模式,js作為一門無類的語言。使用全局變量的模式來實現單例模式思想。js里面的單例又分為普通單例和惰性單例,惰性單例指的是只有這個實例...
閱讀 2964·2023-04-26 02:04
閱讀 1278·2021-11-04 16:07
閱讀 3699·2021-09-22 15:09
閱讀 678·2019-08-30 15:54
閱讀 1899·2019-08-29 14:11
閱讀 2525·2019-08-26 12:19
閱讀 2255·2019-08-26 12:00
閱讀 752·2019-08-26 10:27