设计模式-javascript实现【职责链模式】
定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成
一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
1. 实现职责链
// 定义职责链
class Chain {
constructor(fn){
this.fn = fn;
this.successor = null;
}
// 设置下一个节点
setNextSuccessor(successor){
return this.successor = successor;
}
// 传递或者执行请求
passRequest(){
const ret = this.fn.apply(this, arguments);
if(ret === 'nextSuccessor'){
return this.successor && this.successor.passRequest.apply(this.successor, arguments);
}
return ret;
}
// 异步职责链可以直接调用next方法
next(){
return this.successor && this.successor.passRequest.apply(this.successor, arguments);
}
}
// 定义职责链上的节点
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 chainOrder500 = new Chain(order500);
const chainOrder200 = new Chain(order200);
const chainOrderNormal = new Chain(orderNormal)
chainOrder500.setNextSuccessor(chainOrder200).setNextSuccessor(chainOrderNormal);
chainOrder500.passRequest(3, true, 500);
/** 异步职责调用 **/
const fn1 = new Chain(function(){
console.log(1);
return 'nextSuccessor';
});
const fn2 = new Chain(function(){
console.log(2);
const self = this;
setTimeout(function(){
self.next();
}, 1000);
});
const fn3 = new Chain(function(){
console.log(3);
});
fn1.setNextSuccessor(fn2).setNextSuccessor(fn3);
fn1.passRequest();
2. 用AOP实现职责链
// 定义函数链
Function.prototype.after = function(fn){
const self = this;
return function(){
const ret = self.apply(this, arguments);
if(ret === 'nextSuccessor'){
return fn.apply(this, arguments);
}
return ret;
};
}
// 定义函数节点
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 order = order500.after(order200).after(orderNormal);
order(2, true, 500);