職責鏈模式在咱們的開發中很是常見,然而在不知道的同窗那裏,可能你以前都是經過if/else的方式來實現的相似邏輯。職責鏈主要就是指,在執行一個具體的事情時,不肯定使用哪一種邏輯時,進行鏈式的判斷,直到找到符合條件的函數或者對象,而後處理。分析,發現其實咱們不少的代碼的背後邏輯就是職責鏈模式。javascript
現實中的例子很是多,好比,咱們在擠公交時,若是人特別多,咱們以前是將硬幣經過人傳遞的方式,依次向前傳遞,直到前面的人是司機或者售票員,這就是一個很是明顯的職責鏈的例子。java
原先的代碼主要是經過if,else進行不斷的判斷,執行不一樣的邏輯。設計模式
const order = (orderType,pay,stock){
if(orderType === 1){
if(pay === true){
console.log('500元定金,返回100優惠券')
} else {
if(stock > 0 ){
consle.log('普通購買,無優惠券')
} else {
console.log('庫存不足')
}
}
}
else if(orderType === 2){
if(pay === true){
console.log('200元定金,返回50優惠券')
} else {
if(stock > 0 ){
consle.log('普通購買,無優惠券')
} else {
console.log('庫存不足')
}
}
}else{
if(stock > 0 ){
consle.log('普通購買,無優惠券')
} else {
console.log('庫存不足')
}
}
}
複製代碼
咱們按照職責鏈的設計思想,一步到位,分別包含如下的思路:app
const order500 = function(orderType,pay,stock){
if(orderType === 1 && pay === true){
console.log('500元定金,返回100優惠券')
} else {
return 'nextSuccessor';
}
}
const order200 = function(orderType,pay,stock){
if(orderType === 2 && pay === true){
console.log('200元定金,返回50優惠券')
} else {
return 'nextSuccessor';
}
}
const orderNormal = function(orderType,pay,stock){
if(stock > 0 ){
console.log('普通購買,無優惠券')
} else {
console.log('庫存不足')
}
}
const Chain = function(fn){
this.fn = fn;
this.successor = null;
}
Chain.prototype.setNextSuccessor = function(successor){
return this.successor = successor;
}
Chain.prototype.passRequest = function(){
let ret = this.fn.apply(this, arguments);
if(ret === 'nextSuccessor'){
return this.successor && this.successor.passRequest.apply(this.successor, arguments);
}
return ret;
}
let chainOrder500 = new Chain(order500);
let chainOrder200 = new Chain(order200);
let chainOrderNormal = new Chain(orderNormal);
chainOrder500.setNextSuccessor(chainOrder200);
chainOrder200.setNextSuccessor(chainOrderNormal);
chainOrder500.passRequest(1,false,0);
chainOrder500.passRequest(1,true,10);
chainOrder500.passRequest(2,true,11);
chainOrder500.passRequest(2,false,1);
複製代碼
codepen地址:codepen.io/robinson90/…函數
文章連接:mp.weixin.qq.com/s/qQEEnf79F…學習
引入職責驅動概念,從知識的能力的角度,去判斷哪一個對象具備操做的能力。ui
但這樣的壞處是當加入新的狀態時,全部實現接口的狀態類都須要變動,不符合設計模式的開閉原則。this
狀態圖:spa
這種不在典型的職責鏈設計中,是我我的在開發過程當中,本身認爲的也符合形式上的鏈式判斷,但最終只肯定執行一個最終函數,而不是實現鏈式遞交的。prototype
固然了,也可能這徹底不屬於任何一種設計模式,不過我以爲設計模式的本質仍是爲了解決固定場景的固定思惟模式,至於叫什麼名字應該不是重點。
具體代碼以下:
let Chain = function(){
let dutyArr = []
this.addDuty = function(duty){
dutyArr.push(duty)
}
this.opt = function(params){
for(let index in dutyArr){
if(dutyArr[index].judge(params)){
return dutyArr[index].opt && dutyArr[index].opt(params);
}
}
return false
}
}
let ageChainDemo = new Chain();
ageChainDemo.addDuty({
judge:function(params){
let {age} = params;
return age > 18;
},
opt:function(params){
let {age} = params;
return '你已是成年人了'
}
})
ageChainDemo.addDuty({
judge:function(params){
let {age} = params;
return age > 0 && age < 18;
},
opt:function(params){
let {age} = params;
return '你仍是未成年'
}
})
let result = ageChainDemo.opt({age:20});
console.log(result);
let result2 =ageChainDemo.opt({age:10});
console.log(result2);
複製代碼
codepen地址:codepen.io/robinson90/…
乍一看,寫法上,職責鏈與策略模式沒什麼,都是分別維護不一樣的函數邏輯,其區別主要是使用條件的判斷。
策略模式能夠準確的決定使用哪一種策略,並且能夠肯定使用這種策略就能返回結果;而職責鏈模式,則是將使用條件進行抽象,內置到函數中,經過不斷的函數內部判斷,若是不符合,須要繼續判斷傳遞,直到執行到符合條件的函數並執行。
由此,咱們能夠這樣斷定,若是咱們對條件屬於模糊的,更適合使用職責鏈。這樣要好於寫if/else內寫複雜的布爾運算,或者使用某個計算變量的結果值,或者使用其餘函數的返回結果。
原文連接:www.yuque.com/robinson/de…
更多設計模式的學習與瞭解,能夠移步到個人設計模式專輯:www.yuque.com/robinson/de…