- /**
- * pre:职责链模式
- * 定义:一系列可能处理请求的对象链接成一条链,
- * 请求在这条链中传递,直到遇到一个可以处理它的对象。
- */
- // --------- 示例 1 -----------
- /**
- * 某品牌手机销售,交500元定金可得100元电商优惠券,交300元可得50元优惠券,
- * 没有交定金的用户只能进行普通购买,而且还不一定能买的到。
- * 将这一过程用代码写出来:
- * orderType: 1,交500定金;2,交300元定金,3,普通购买
- * pay:true 已支付定金,false未支付定金
- * stock:手机库存数
- */
- var order = (function() {
- var favorCache = { // 优惠配置
- 1 : [500, 100],
- 2 : [300, 50]
- };
- var normal = function(stock) { // 普通购买
- if (stock > 0) {
- console.log("普通购买.库存数:" + stock);
- } else {
- console.log("库存不足.");
- }
- };
- var preOrder = function(orderType, pay) { // 预付定金
- if (orderType in favorCache && pay) {
- console.log("支付定金:" + favorCache[orderType][0] + ",获得" + favorCache[orderType][1] + "元优惠券.");
- return true;
- }
- return false;
- };
- return function(orderType, pay, stock) {
- preOrder(orderType, pay) || normal(stock);
- }
- })();
- order(1, true, 500);
- order(1, false, 500);
- order(2, true, 200);
- order(3, false, 100);
- order(3, false, 0);
- // ------------- 示例2 --------------
- /*
- * 使用职责链模式实现功能
- */
- var order500 = function(orderType, pay, stock) {
- if (orderType === 1 && pay) {
- console.log("支付定金:500元,获得100元优惠券.");
- } else {
- order300(orderType, pay, stock);
- }
- };
- var order300 = function(orderType, pay, stock) {
- if (orderType === 2 && pay) {
- console.log("支付定金:300元,获得50元优惠券.");
- } else {
- orderNormal(orderType, pay, stock);
- }
- };
- var orderNormal = function(orderType, pay, stock) {
- if (stock > 0) {
- console.log("普通购买.库存数:" + stock);
- } else {
- console.log("库存不足.");
- }
- };
- order500(1, true, 500);
- order500(1, false, 500);
- order500(2, true, 200);
- order500(3, false, 100);
- order500(3, false, 0);
- /**
- * 不足:虽然把函数拆分成互不影响的3个小函数,但是传递请求的代码被耦合在业务函数之中,
- * 这样的请求传递非常的僵硬,也违背了开放-封闭原则。
- */
- //--------------- 示例3 -------------
- /**
- * 改进上面的职责链模式,让每个节点可以单独拆分和重组.
- */
- var order500 = function(orderType, pay, stock) {
- if (orderType === 1 && pay) {
- console.log("支付定金:500元,获得100元优惠券.");
- } else {
- return "next";
- }
- };
- var order300 = function(orderType, pay, stock) {
- if (orderType === 2 && pay) {
- console.log("支付定金:300元,获得50元优惠券.");
- } else {
- return "next";
- }
- };
- var orderNormal = function(orderType, pay, stock) {
- if (stock > 0) {
- console.log("普通购买.库存数:" + stock);
- } else {
- console.log("库存不足.");
- }
- };
- // -- 定义链节点函数 --
- var Chain = function(fn) {
- this.fn = fn;
- this.next = null;
- };
- Chain.prototype.setNext = function(next) {
- this.next = next;
- };
- Chain.prototype.passRequest = function() {
- var result = this.fn.apply(this, arguments);
- if ("next" === result) {
- return this.next && this.next.passRequest.apply(this.next, arguments);
- }
- return result;
- };
- var chain500 = new Chain(order500);
- var chain300 = new Chain(order300);
- var chainNormal = new Chain(orderNormal);
- chain500.setNext(chain300);
- chain300.setNext(chainNormal);
- chain500.passRequest(1, true, 500);
- chain500.passRequest(1, false, 500);
- chain500.passRequest(2, true, 200);
- chain500.passRequest(3, false, 100);
- chain500.passRequest(3, false, 0);
- //---------- 示例4 -----------
- /**
- * 上个示例中,已经实现了一个职责链模式,但在现实中,我们往往是
- * 根据一个异步请求的结果,来决定是否执行下一个函数。
- */
- var Chain = function(fn) {
- this.fn = fn;
- this.next = null;
- };
- Chain.prototype.setNext = function(next) { // 设置下一个执行函数
- return this.next = next;
- };
- Chain.prototype.passRequest = function() { // 传递请求
- var result = this.fn.apply(this, arguments);
- if ("next" === result) {
- return this.next && this.next.passRequest.apply(this.next, arguments);
- }
- return result;
- };
- Chain.prototype.executeNext = function() { // 主动执行下一个函数
- return this.next && this.next.passRequest.apply(this.next, arguments);
- };
- var fn1 = new Chain(function() {
- console.log(1);
- return "next";
- });
- var fn2 = new Chain(function() {
- console.log(2);
- var self = this;
- setTimeout(function() {
- self.executeNext();
- },
- 2000); // 模拟异步回调
- });
- var fn3 = new Chain(function() {
- console.log(3);
- });
- fn1.setNext(fn2).setNext(fn3);
- fn1.passRequest();
- /**
- * 经过这些例子,我们总结一下职责链模式的优缺点:
- * 优点:
- * 1、各个处理函数互不影响,各自独立;
- * 2、删除、增加节点比较灵活,不需要改动其他函数的代码;
- * 3、可以手动指定起始节点。比如手机商城的例子,付过定金的订单全部结束购买流程后,
- * 完全可以把请求交给普通订单处理:orderNormal(1,false,500);
- * 缺点:
- * 1、我们不能保证某个请求一定会被职责链中的节点处理;
- * 2、某些请求被处理时,可能会经历多个节点,会给系统带来性能损耗。
- */
- // ----------- 示例5 --------------
- /**
- * 利用js函数式的特性,创建职责链
- */
- Function.prototype.after = function(fn) {
- var self = this;
- return function() {
- var result = self.apply(this, arguments);
- if ("next" === result) {
- return fn.apply(this, arguments);
- }
- return result;
- }
- };
- var fn1 = function() {
- console.log(1);
- return "next";
- };
- var fn2 = function() {
- console.log(2);
- return "next";
- };
- var fn3 = function() {
- console.log(3);
- };
- var ff = fn1.after(fn2).after(fn3);
- ff();
来源: http://www.cnblogs.com/stinchan/p/7057818.html