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