### 一、定義
責任鏈模式:使多個對象都有機會處理請求,從而避免請求的發送者和接受者之間的耦合關系,將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理它為止。
### 二、示例
> 假設這么一個場景:
我們負責一個售賣手機的電商網站,經過分別繳納500元定金和200元定金的兩輪預定后,到了正式購買階段。針對預定用戶實行優惠,支付過500元定金的用戶會收到100元的商城優惠券,支付過200元定金的用戶會收到50元的商城優惠券,沒有支付定金的用戶歸為普通購買,且在庫存有限的情況下不一定保證買到。
~~~
/* 傳統方式實現 */
// orderType:[1:500, 2:200, 3:普通],isPaid:true/false,stock:庫存量
var order = function(orderType, isPaid, stock) {
if(orderType === 1) {
if(isPaid) {
console.log("500元定金預購,得到100優惠券");
} else {
if(stock > 0) {
console.log("普通購買,無優惠券");
}else {
console.log("庫存不足");
}
}
}else if(orderType === 2) {
if(isPaid) {
console.log("200元定金預購,得到50優惠券");
} else {
if(stock > 0) {
console.log("普通購買,無優惠券");
}else {
console.log("庫存不足");
}
}
}else if(orderType === 2) {
if(stock > 0) {
console.log("普通購買,無優惠券");
}else {
console.log("庫存不足");
}
}
}
order(1, true, 500);
/*職責鏈 */
var order500 = function(orderType, isPaid, stock) {
if(orderType === 1 && isPaid === true) {
console.log("500元定金預購,得到100優惠券");
}else {
return "nextSuccessor";
}
};
var order200 = function(orderType, isPaid, stock) {
if(orderType === 2 && isPaid === true) {
console.log("200元定金預購,得到50優惠券");
}else {
return "nextSuccessor";
}
};
var orderNormal = function(orderType, isPaid, stock) {
if(stock > 0) {
console.log("普通購買,無優惠券");
}else {
console.log("庫存不足");
}
};
Function.prototype.after = function(fn) {
var self = this;
return function() {
var ret = self.apply(this, arguments);
if(ret === "nextSuccessor") {
return fn.apply(this, arguments);
}
return ret;
};
}
var order = order500.after(order200).after(orderNormal);
order(1, true, 10);
~~~
**優點:解耦了請求發送者和N個接受者之間的復雜關系。**
**弊端:不能保證某個請求一定會被鏈中的節點處理。**
### 三、示例:文件上傳對象
示例2:用責任鏈模式獲取文件上傳對象
PS:對比[《JavaScript設計模式–迭代器模式》](http://blog.csdn.net/ligang2585116/article/details/50365246)
~~~
function getActiveUploadObj() {
try{
return new ActiveObject("TXFTNActiveX.FTNUpload"); // IE上傳控件
}catch(e) {
return "nextSuccessor";
}
}
function getFlashUploadObj() {
if(supportFlash().f === 1) { // supportFlash見《JavaScript設計模式--迭代器模式》
var str = '<object type="application/x-shockwave-flash"></object>';
return $(str).appendTo($("body"));
}
return "nextSuccessor";
}
function getFormUploadObj() {
var str = '<input name="file" type="file" class="ui-file" />';
return $(str).appendTo($("body"));
}
var getUploadObj = getActiveUploadObj.after(getFlashUploadObj).after(getFormUploadObj);
console.log(getUploadObj());
~~~
無論是作用域鏈、原型鏈、還是DOM節點中的事件冒泡,我們都能從中找到職責鏈的影子。
轉載請標明出處:[http://blog.csdn.net/ligang2585116](http://blog.csdn.net/ligang2585116)