• javascript 责任链模式 Chain of Responsibility


    * 可拆分的责任链节点

    // 可拆分的责任链节点
    // Chain.prototype.setNextSuccessor  指定在链条中的下一个节点
    // Chain.prototype.passRequest  传递请求给某个节点
    
    function Chain(fn) {
    	this.fn = fn;
    	this.successor = null;
    }
    
    Chain.prototype.setNextSuccessor = function(successor) {
    	return this.successor = successor;
    }
    
    Chain.prototype.passRequest = function() {
    	var ret = this.fn.apply(this, arguments);
    	if (ret === "nextSuccessor") {
    		return this.successor 
    			&& this.successor.passRequest.apply(this.successor, arguments);
    	}
    	return ret;
    }
    
    // 3个订单函数
    // @orderType:
    //   1=>500元定金
    //   2=>200元定金
    //   3=>普通购买用户
    // @pay: 用户是否已经支付定金 (下定金未支付?)
    // @stock:  SKU 库存数量
    var order500 = function(orderType, pay, stock) {
    	if (orderType === 1 && pay===true) {
    		console.log("500元定金订购,得到100元优惠券。");
    	} else {
    		// 把请求往后面传递
    		return "nextSuccessor";
    	}
    }
    var order200 = function(orderType, pay, stock) {
    	if (orderType === 2 && pay===true) {
    		console.log("200元定金订购,得到50元优惠券。");
    	} else {
    		return "nextSuccessor";
    	}
    }
    var orderNormal = function(orderType, pay, stock) {
    	if (stock > 0) {
    		console.log("普通购买, 无优惠券。");
    	} else {
    		console.log("手机库存不足。");
    	}
    }
    
    // 把3个订单函数分别包装成责任链的节点
    var chainOrder500 = new Chain(order500);
    var chainOrder200 = new Chain(order200);
    var chainOrderNormal = new Chain(orderNormal);
    
    // 指定节点在责任链中的顺序
    chainOrder500.setNextSuccessor(chainOrder200);
    chainOrder200.setNextSuccessor(chainOrderNormal);
    
    // test: 把请求传递给第1个节点
    chainOrder500.passRequest(1, true, 300);
    chainOrder500.passRequest(2, true, 299);
    chainOrder500.passRequest(3, true, 298);
    chainOrder500.passRequest(1, false, 0);
    
    // 后期新增优惠规则 300元定金订购
    var order300 = function(orderType, pay, stock) {
    	if (orderType === 4 && pay===true) {
    		console.log("300元定金订购,得到60元优惠券。");
    	} else {
    		return "nextSuccessor";
    	}
    }
    var chainOrder300 = new Chain(order300);
    chainOrder500.setNextSuccessor(chainOrder300);
    chainOrder300.setNextSuccessor(chainOrder200);
    
    chainOrder500.passRequest(4, true, 297);
    

      output:

    500元定金订购,得到100元优惠券。
    200元定金订购,得到50元优惠券。
    普通购买, 无优惠券。
    手机库存不足。
    300元定金订购,得到60元优惠券。

     * 异步的责任链

    function Chain(fn) {
    	this.fn = fn;
    	this.successor = null;
    }
    
    Chain.prototype.setNextSuccessor = function(successor) {
    	return this.successor = successor;
    }
    
    Chain.prototype.passRequest = function() {
    	var ret = this.fn.apply(this, arguments);
    	if (ret === "nextSuccessor") {
    		return this.successor 
    			&& this.successor.passRequest.apply(this.successor, arguments);
    	}
    	return ret;
    }
    
    Chain.prototype.next = function() {
    	return this.successor &&
    		this.successor.passRequest.apply(this.successor, arguments);
    }
    
    var fn1 = new Chain(function() {
    	console.log(1);
    	return 'nextSuccessor';
    });
    
    var fn2 = new Chain(function() {
    	console.log(2);	
    	var self = this;
    	setTimeout(function() {
    		self.next();
    	}, 1000);
    	// return 'nextSuccessor';
    });
    
    var fn3 = new Chain(function() {
    	console.log(3);
    });
    
    fn1.setNextSuccessor(fn2).setNextSuccessor(fn3);
    fn1.passRequest();
    

      Run:

    * 使用aop实现责任链

    // 3个订单函数
    // @orderType:
    //   1=>500元定金
    //   2=>200元定金
    //   3=>普通购买用户
    // @pay: 用户是否已经支付定金 (下定金未支付?)
    // @stock:  SKU 库存数量
    var order500 = function(orderType, pay, stock) {
    	if (orderType === 1 && pay===true) {
    		console.log("500元定金订购,得到100元优惠券。");
    	} else {
    		// 把请求往后面传递
    		return "nextSuccessor";
    	}
    }
    var order200 = function(orderType, pay, stock) {
    	if (orderType === 2 && pay===true) {
    		console.log("200元定金订购,得到50元优惠券。");
    	} else {
    		return "nextSuccessor";
    	}
    }
    var orderNormal = function(orderType, pay, stock) {
    	if (stock > 0) {
    		console.log("普通购买, 无优惠券。");
    	} else {
    		console.log("手机库存不足。");
    	}
    }
    
    // 使用aop实现责任链
    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, 500);
    order(2, true, 500);
    order(1, false, 500);

      

    Run:

  • 相关阅读:
    Google官方关于Android架构中MVP模式的示例续-DataBinding
    值不值
    [译]Godot系列教程五
    [译]Google官方关于Android架构中MVP模式的示例
    遭遇Web print
    如何寻找有价值的点
    充电时间 Go中的数组、切片、map简单示例
    一段良好的程序永远不应该发生panic异常
    居然是Firefox没有抛弃我们
    macOS 升级到了10.12.1
  • 原文地址:https://www.cnblogs.com/mingzhanghui/p/9405482.html
Copyright © 2020-2023  润新知