摘要:提交請求的對象并不明確知道哪一個對象將會處理它也就是該請求有一個隱式的接受者。
20190412期
設計模式-如何理解職責鏈模式?
定義: 使多個對象都有機會處理請求,從而避免請求的發(fā)送者和接收者之間的耦合關系,將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理它為止
也就是說,請求以后,從第一個對象開始,鏈中收到請求的對象要么親自處理它,要么轉發(fā)給鏈中的下一個候選者。提交請求的對象并不明確知道哪一個對象將會處理它——也就是該請求有一個隱式的接受者(implicit receiver)。根據(jù)運行時刻,任一候選者都可以響應相應的請求,候選者的數(shù)目是任意的,你可以在運行時刻決定哪些候選者參與到鏈中
還不明白?ok, 來個生活小實例, 早高峰擠公交車,往往擠上去卻看不到售票員,我們常常通過他人之手將票錢傳遞給售票員,這種關系就能看做為職責鏈,我們的票錢通過多人之手最終遞交到售票員手中
代碼場景:
假設我們正在開發(fā)一個電商網(wǎng)站,某一個商品正在進行預定活動,活動規(guī)則如下
500 元定金會收到200 優(yōu)惠劵
200 元定金會收到100 優(yōu)惠劵
沒有預定的用戶只能普通購買
假設我們后端會返回如下字段
orderType [1,2,3] 分別為500,200,普通購買
常規(guī)實現(xiàn):
const order = function(orderType){ if(orderType===1){ // 假設我們有其它需求 if(....){ ..... } return console.log(500元定金用戶) } if(orderType===2){ // 假設我們有其它需求 if(....){ ..... } return console.log(200元定金用戶) } if(orderType===3){ // 假設我們有其它需求 if(....){ ..... } return console.log(用戶普通購買) } } order(1) // 500元定金用戶
雖然我們得到了意料中的運行結果,但這并不是一段優(yōu)秀的代碼,order函數(shù)會隨著業(yè)務的變更經(jīng)常修改
下面我們用職責鏈模式進行改寫
const Chain = function(fn){ this.fn = fn; this.successor = null; } Chain.prototype.setNextSuccessor = function(successor){ 指定在鏈中的下一個節(jié)點 return this.successor = successor; } Chain.prototype.passRequest = function(){ //傳遞請求給某一下節(jié)點 var ret = this.fn.apply(this,arguments); if(ret === false){ // 如果ret 為false 代表鏈條還得繼續(xù)往下走 return this.successor && this.successor.passRequest.apply(this.successor,arguments) } } // 包裝成職責鏈的節(jié)點 var chainOrder500 = new Chain(order500); var chainOrder200 = new Chain(order200); // 然后再指定節(jié)點在鏈中的順序 chainOrder500.setNextSuccessor(chainOrder200) // 最后把請求傳遞給第一個節(jié)點 chainOrder500.passRequest(1) // 500元定金用戶
用AOP實現(xiàn)職責鏈又簡單又巧妙,但這種函數(shù)疊加在一起的方式,同時也疊加了函數(shù)的作用域,如果鏈條太長也會對性能造成影響
Function.prototype.after(fn){ var _this = this; return function(){ var ret = _this.apply(this,arguments); if(ret === false){ return fn.apply(this.arguments); } return ret } } var order = order500.after(order200).after(orderNormal); order(2) // 200定金用戶總結
職責鏈模式可以很好的幫助我們管理代碼,降低發(fā)起請求的對象跟接收請求對象的耦合,職責鏈中的節(jié)點順序是可變化的,我們可以在運行中決定鏈中包含哪些節(jié)點
關于JS每日一題JS每日一題可以看成是一個語音答題社區(qū)
每天利用碎片時間采用60秒內(nèi)的語音形式來完成當天的考題
群主在次日0點推送當天的參考答案
注 絕不僅限于完成當天任務,更多是查漏補缺,學習群內(nèi)其它同學優(yōu)秀的答題思路
點擊加入答題
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/103534.html
20190124問: 如何理解es6中的Proxy? 試題解析:對proxy的理解,可能會延伸到vue的雙向綁定 Proxy(代理) 定義 可以理解為為目標對象架設一層攔截,外界對該對象的訪問,都必須通過這層攔截 簡單示例: const obj = new Proxy({}, { get: (target, key, receiver) => { return JS ...
20190124問: 如何理解es6中的Proxy? 試題解析:對proxy的理解,可能會延伸到vue的雙向綁定 Proxy(代理) 定義 可以理解為為目標對象架設一層攔截,外界對該對象的訪問,都必須通過這層攔截 簡單示例: const obj = new Proxy({}, { get: (target, key, receiver) => { return JS ...
閱讀 1890·2021-11-25 09:43
閱讀 3180·2021-11-15 11:38
閱讀 2723·2019-08-30 13:04
閱讀 497·2019-08-29 11:07
閱讀 1510·2019-08-26 18:37
閱讀 2748·2019-08-26 14:07
閱讀 598·2019-08-26 13:52
閱讀 2295·2019-08-26 12:09