例子
- 充值 500 (orderType = 1),100%(isPay 充值成功)中 100 的优惠券
- 充值 200 (orderType = 2),100%(isPay 充值成功)中 20 的优惠券
- 不充值(orderType = 3),根据优惠券的库(count)存来决定,有机会中 10 的优惠券
var order = function(orderType, isPay, count) {
if(orderType === 1) {
// 充值 500
if(isPay) {
// 充值成功,100% 中奖
console.log("恭喜中奖 100 优惠券");
} else {
if(count > 0) {
console.log("恭喜中奖 10 优惠券");
} else {
console.log("很遗憾没有优惠券");
}
}
} else if(orderType === 2) {
// 充值 200
if(isPay) {
// 充值成功,100% 中奖
console.log("恭喜中奖 20 优惠券");
} else {
if(count > 0) {
console.log("恭喜中奖 10 优惠券");
} else {
console.log("很遗憾没有优惠券");
}
}
} else if(orderType === 3) {
if(count > 0) {
console.log("恭喜中奖 10 优惠券");
} else {
console.log("很遗憾没有优惠券");
}
}
}
使用责任链模式进行优化
把各种模式单独地抽离出来 ```javascript function order500(orderType, isPay, count) { if(orderType ==== 1 && isPay) { console.log(“恭喜中奖 100 优惠券”); } else { return “next”; } }
function order200(orderType, isPay, count) { if(orderType ==== 2 && isPay) { console.log(“恭喜中奖 20 优惠券”); } else { return “next”; } }
function orderNormal(orderType, isPay, count) { if(count > 0) { console.log(“恭喜中奖 10 优惠券”); } else { console.log(“很遗憾没有优惠券”); } }
通过一种方式把三种模式串成一条链条,也就是 Chain 函数:
```javascript
var Chain = function(fn) {
this.fn = fn;
this.next = null;
}
Chain.prototype.setNext = function(nextChain) {
return (this.next = nextChain);
}
Chain.prototype.passRequest = function() {
var res = this.fn.apply(this, arguments);
if(res === "next") {
return this.next && this.next.passRequest.apply(this.next, arguments);
}
return res;
}
使用先用 Chain 包装一下每一个模式的函数,并设置各自的 nextChain 来指定链条的顺序
使用 passRequest 来调用
var chainOrder500 = new Chain(order500);
var chainOrder200 = new Chain(order200);
var chainOrderNormal = new Chain(orderNormal);
chainOrder500.setNext(chainOrder200);
chainOrder200.setNext(chainOrderNormal);
chainOrder500.passRequest(1, true, 500);
chainOrder500.passRequest(2, true, 500);
chainOrder500.passRequest(3, true, 500);
chainOrder500.passRequest(1, false, 500);
chainOrder500.passRequest(1, false, 0);
责任链模式结合 AOP 来作优化
不使用 Chain 的方式来传递函数,而通过 AOP 的 after
Function.prototype.after = function(fn) {
var _this = this;
return function() {
var res = _this.apply(this, arguments);
if(res === 'next') {
return fn.apply(this, arguments);
}
return res;
}
}
var order = order500.after(order200).after(orderNormal);
order(1, true, 500);
order(2, true, 500);
order(3, true, 500);
order(1, false, 500);
order(1, false, 0);