JavaScript 实现职责链模式概述

作者:闭包旅人时间:2026-10-22 12:03:17浏览:623

本文介绍 JavaScript 中通过 AOP 方式实现职责链模式的方法。通过 Function.prototype.after 扩展,将多个处理函数串联成链,请求沿链传递直至被处理。相比传统 if-else 嵌套,该方式实现了函数间的高度解耦,便于新增处理逻辑而不修改原有代码。

职责链模式概述

什么是职责链模式

职责链模式的核心定义在于:让多个对象都有机会处理同一个请求,从而消除请求发送者与具体接收者之间的紧密耦合。这些对象被连接成一条链,请求沿着这条链传递,直到链上的某个对象最终处理该请求为止。一个通俗的类比是:乘客从公交车后门上车后,无法直接将硬币投入收款箱,因为不清楚收款箱的具体位置。因此,乘客将硬币交给前一个人,由他再传给下一个人,如此依次传递,直到硬币到达站在收款箱旁的人手中,由他将钱放入箱内。

职责链模式思想

在职责链模式中,请求发送者只需知晓链中的第一个节点,从而弱化了发送者与一组接收者之间的强联系。

JavaScript AOP 实现方式

JavaScript实现职责链模式(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;
  }
 }

在 JavaScript 中实现职责链模式相对简单。若对前述 AOP 代码有疑问,可参考之前撰写的《JavaScript实现AOP》一文。这种实现方式在代码形态上与装饰者模式相似,但两者的设计出发点截然不同。

AOP实现装饰者模式:在不改变已有函数内部逻辑的前提下,为其添加新功能。可以将其想象为同心圆,每次调用 after 方法,相当于在原有函数外层包裹一层新的功能,它们之间是包含关系。

AOP实现职责链模式:在函数执行后,根据返回值决定是否执行链中的下一个函数。每次调用 after,相当于在现有函数之后追加一个处理函数,是否执行后续函数取决于前一个函数的返回值。它们之间是链式关系。

职责链模式实例分析

职责链模式实例


function cat (type) {
  if(type == "cat") {
    console.log("我是猫猫");
  } else {
    return "nextSuccessor"
  }
}

function dog (type) {
  if(type == "dog") {
    console.log("我是狗狗");
  } else {
    return "nextSuccessor"
  }
}

function pig (type) {
  if(type == "pig") {
    console.log("我是猪猪");
  } else {
    return "nextSuccessor"
  }
}

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 pet = cat.after(dog).after(pig);

pet("pig"); //我是猪猪
pet("dog"); //我是狗狗
pet("cat"); //我是猫猫

观察上述代码,向 pet 方法传入三个不同参数时,会得到不同的处理结果。以第一次调用为例,执行过程如下:传入“pig”,首先由 cat 方法判断,cat 发现无法处理该请求,于是返回“nextSuccessor”将“pig”传递给 dog 方法;dog 方法同样无法处理,继续将“pig”传递给 pig 方法;pig 方法能够处理该请求,最终在控制台打印出“我是猪猪”。

读者可能会质疑:上述功能仅用几行代码即可实现,为何还要编写如此复杂的代码?


function pet(type) {
  if(type == "cat") {
    console.log("我是猫猫");
  } else if(type == "dog") {
    console.log("我是狗狗");
  } else if(type == "pig") {
    console.log("我是猪猪");
  }
}

pet("pig"); //我是猪猪
pet("dog"); //我是狗狗
pet("cat"); //我是猫猫

表面上看,传统写法确实更简洁。但需考虑扩展性:若未来新增“猴子”这一动物,使用传统代码需修改 pet 函数源码,添加一条 if 语句判断是否为猴子。若新增一万种动物,则需在 pet 函数中添加一万条 if 语句。更复杂的情况是,若一种动物还有多个品种(如猫咪分为长毛猫、短毛猫),代码将陷入深层嵌套的 if 语句中。这种写法不仅难以维护,且代码结构混乱。

然而,若采用职责链模式,每新增一种动物,只需定义一个对应的处理函数,并将其添加到职责链中即可。这样,新函数与原有函数之间实现了高度解耦,代码结构更加清晰优雅。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章