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