JavaScript设计模式:责任链模式详解与实战

作者:半夏时间:2026-10-29 20:35:06浏览:91

本文深入解析JavaScript中的责任链模式,通过电商订单优惠场景演示如何解耦请求发送者与多个接收者。文章提供了从传统嵌套逻辑到链式调用的代码重构示例,并探讨了该模式在获取文件上传对象(如ActiveX、Flash、Form)中的实际应用,帮助开发者理解并掌握这一重要设计模式。

责任链模式定义

一、定义

责任链模式的核心在于让多个对象都有机会处理请求,从而避免请求发送者与接收者之间的紧密耦合。这些对象被连接成一条链,请求沿着这条链传递,直到有对象将其处理为止。

电商订单场景示例

二、示例

  • 假设存在以下业务场景:
  • 我们运营一个手机电商网站,经过两轮预定(分别缴纳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设计模式之迭代器模式》

实战应用:文件上传对象获取


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节点中的事件冒泡,我们都能从中找到职责链的影子。

以上就是本文的全部内容,希望本文所述对大家学习javascript程序设计有所帮助。。

作者最新文章