javascript設(shè)計模式 – 職責(zé)鏈模式原理與用法實例分析
本文實例講述了javascript設(shè)計模式 – 職責(zé)鏈模式原理與用法。分享給大家供大家參考,具體如下:
介紹:很多情況下,在一個軟件系統(tǒng)中可以處理某個請求的對象不止一個。例如一個網(wǎng)絡(luò)請求過來,需要有對象去解析request Body,需要有對象去解析請求頭,還需要有對象去對執(zhí)行對應(yīng)controller。請求一層層傳遞,讓每一個對象都基于請求完成自己的任務(wù),然后將請求傳遞給下一個處理程序。是不是感覺有點中間件的感覺。
定義:職責(zé)鏈就是避免請求發(fā)送者與接收者耦合在一起,讓多個對象都有可能接收請求。將這些對象連成一條鏈,并沿著鏈傳遞請求,直到有對象處理它為止。職責(zé)鏈模式是一種對象行為型模式。
場景:我們繼續(xù)畫圓,我們準(zhǔn)備了兩組示例:
示例:
var Circle = function(){ this.radius = 0; this.drawByRadius = function(radius){ if(radius < 5){ this.drawVerySmalCircle(); }else if(radius < 10){ this.drawSmalCircle(); }else if(radius < 15){ this.drawMediumCircle(); }else if(radius < 20){ this.drawBigCircle(); }else{ this.drawVeryBigCircle(); } } this.drawVerySmalCircle = function(){ console.log('畫一個超小的圓( 5以下 )'); } this.drawSmalCircle = function(){ console.log('畫一個小圓( 5-10 )'); } this.drawMediumCircle = function(){ console.log('畫一個中圓 ( 10-15 )'); } this.drawBigCircle = function(){ console.log('畫一個大圓 ( 15-20 )'); } this.drawVeryBigCircle = function(){ console.log('畫一個超大的圓 ( 20以上 )'); } } var circle = new Circle(); circle.drawByRadius(30); //畫一個超大的圓 ( 20以上 )
觀察上面的代碼,這是很常見的邏輯,通過參數(shù)來決定執(zhí)行哪個方法。首先drawByRadius方法職責(zé)過重,其次這樣的方式在修改,新增時需要修改源代碼,不符合開關(guān)原則。
我們使用職責(zé)鏈模式重寫下:
var drawSmalCircle = function(min,max){ this.max = max; this.min = min; this.nextCircle; this.setNextDraw = function(circle){ this.nextCircle = circle; } this.draw = function(radius){ console.log('執(zhí)行:drawSmalCircle'); if(this.min < radius && radius < this.max){ console.log('畫一個小圓( 10以下 )'); } if(this.nextCircle){ this.nextCircle.draw(radius) } } } var drawMediumCircle = function(min,max){ this.max = max; this.min = min; this.nextCircle; this.setNextDraw = function(circle){ this.nextCircle = circle; } this.draw = function(radius){ console.log('執(zhí)行:drawMediumCircle'); if(this.min < radius && radius < this.max){ console.log('畫一個中圓 ( 10-20 )'); } if(this.nextCircle){ this.nextCircle.draw(radius) } } } var drawBigCircle = function(min,max){ this.max = max; this.min = min; this.nextCircle; this.setNextDraw = function(circle){ this.nextCircle = circle; } this.draw = function(radius){ console.log('執(zhí)行:drawBigCircle'); if(this.min < radius && radius < this.max){ console.log('畫一個大圓 ( 20以上 )'); } if(this.nextCircle){ this.nextCircle.draw(radius) } } } function initChain(){ var smalCircle = new drawSmalCircle(0,10); var mediumCircle = new drawMediumCircle(10,20); var bigCircle = new drawBigCircle(20,100); smalCircle.setNextDraw(mediumCircle); mediumCircle.setNextDraw(bigCircle); return smalCircle; } var circle = initChain(); circle.draw(30) // 執(zhí)行:drawSmalCircle // 執(zhí)行:drawMediumCircle // 執(zhí)行:drawBigCircle // 畫一個大圓 ( 20以上 circle.draw(15) // 執(zhí)行:drawSmalCircle // 執(zhí)行:drawMediumCircle // 畫一個中圓 ( 10-20 ) // 執(zhí)行:drawBigCircle circle.draw(5) // 執(zhí)行:drawSmalCircle // 畫一個小圓( 10以下 ) // 執(zhí)行:drawMediumCircle // 執(zhí)行:drawBigCircle
以上就是職責(zé)鏈模式的實例代碼,drawSmalCircle,drawMediumCircle,drawBigCircle稱為處理者類,處理者類保存了下一級對象的引用,
當(dāng)我每執(zhí)行一次draw時,程序會挨個執(zhí)行職責(zé)鏈上的每一個方法。
職責(zé)鏈模式分為純職責(zé)鏈和不純職責(zé)鏈,純的職責(zé)鏈在處理請求時,只能選擇全部處理不傳遞或者全部傳遞不處理。我們這里的例子就是不純職責(zé)鏈。它允許處理完成后繼續(xù)向后傳遞。
職責(zé)鏈模式總結(jié):
優(yōu)點:
* 降低耦合,互相都不清楚執(zhí)行順序以及執(zhí)行處理的類。
* 請求對象僅需維持一個指向其后繼者的引用,簡化了對象的相互連接。
* 新增修改職責(zé)鏈結(jié)構(gòu)方便,滿足開關(guān)原則。
缺點:
* 由于沒有明確接受者,可能職責(zé)鏈走到最后都沒有被正確處理。
* 職責(zé)鏈較長時會導(dǎo)致系統(tǒng)性能受影響。
* 建鏈不當(dāng),會造成循環(huán)調(diào)用,導(dǎo)致系統(tǒng)陷入死循環(huán)。
適用場景:
* 多個對象處理同一請求
* 動態(tài)創(chuàng)建執(zhí)行順序,流程
感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運行工具:http://tools.jb51.net/code/HtmlJsRun測試上述代碼運行效果。
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運算用法總結(jié)》
希望本文所述對大家JavaScript程序設(shè)計有所幫助。
相關(guān)文章
JS頁面動態(tài)繪圖工具SVG,Canvas,VML介簡介
這篇文章主要介紹了JS頁面動態(tài)繪圖工具SVG,Canvas,VML介簡介,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10JavaScript性能優(yōu)化之函數(shù)節(jié)流(throttle)與函數(shù)去抖(debounce)
這篇文章主要介紹了JavaScript性能優(yōu)化之函數(shù)節(jié)流(throttle)與函數(shù)去抖(debounce)的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-08-08JavaScript?對象新增方法defineProperty與keys的使用說明
這篇文章主要介紹了JavaScript對象新增方法defineProperty與keys的使用說明,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下2022-09-09javascript設(shè)計模式 – 解釋器模式原理與用法實例分析
這篇文章主要介紹了javascript設(shè)計模式 – 解釋器模式,結(jié)合實例形式分析了javascript解釋器模式相關(guān)概念、原理、用法及操作注意事項,需要的朋友可以參考下2020-04-04JavaScript清除所有(多個)定時器的方法實戰(zhàn)案例
定時器就是由JS提供了一些原生方法來實現(xiàn)延時去執(zhí)行某一段代碼,下面這篇文章主要給大家介紹了關(guān)于JavaScript清除所有(多個)定時器的方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01