JavaScript 实现职责链模式概述
本文介绍 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 语句中。这种写法不仅难以维护,且代码结构混乱。
然而,若采用职责链模式,每新增一种动物,只需定义一个对应的处理函数,并将其添加到职责链中即可。这样,新函数与原有函数之间实现了高度解耦,代码结构更加清晰优雅。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
什么时候该用JS构造器:与工厂模式、字面量的选择对比
2026-11-05 16:18:22
推荐几款轻量级JS照片墙开源库及对比
2026-11-05 15:56:19
JavaScript递归写法有哪些常见陷阱及避免方法
2026-11-05 14:53:38
JS数组浅拷贝与深拷贝怎么选?场景与方法总结
2026-11-05 14:41:02
p5.js 中 setup() 和 draw() 函数的执行机制详解
2026-11-05 12:32:38
