什么是职责链模式
职责链模式的定义是: 使多个对象都有机会处理请求, 从而避免请求的发送者和接收者之间的耦合关系, 将这些对象连成一条链, 并沿着这条链传递该请求, 直到有一个对象处理它为止. 举个例子: 当你从公交车后门上车之后, 你不可能直接把硬币放到收款箱里面, 因为你不知道它在哪, 那你就只能把硬币给你前面一个人, 让他帮你传到前面一个人手上, 这样一直传递到站在收款箱旁边人的手上, 由他把硬币放到收款箱里面.
职责链模式思想
请求发送者只需要知道链中的第一个节点, 从而弱化了发送者和一组接收者之间的强联系.
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 方法发现自己处理不了, 于是把 "pig" 传递给 dog 方法 (return "nextSuccessor" 来表示传递给下一个函数),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 语句判断是不是猴子, 其实这也还好, 如果是加了 1 万种动物呢? 那你就要在 pet 这个函数里添加 1 万条 if 语句, 什么? 还不够浮夸? 那你有没有考虑过一种动物还会分很多品种, 比如说猫咪分为长毛猫, 短毛猫. 这样你的代码就会涉及到嵌套 if 语句. 恕我直言, 现在你的代码已经丑成狗了, 嘻嘻
但是如果使用职责链模式, 每多一个种动物, 我们就给他定义一个函数, 然后添加到职责链上, 这样一来, 新的函数就和原来的函数高度解耦, 岂不美哉?
来源: http://www.jb51.net/article/133661.htm