1. 定义
请求沿着一条链传递,直到有一个对象能够处理它为止
2. 口语化表述
假设某公司的财务审批流程如下:
- 项目经理可以审批1000元以下的费用,大于1000元的费用提交给部门经理审批
- 部门经理可以审批10000元以下的费用,大于10000的费用提交给总经理审批
- 总经理可以审批任何额度的费用
现在,员工报销费用时,只需要提交给自己的项目经理即可,无论数额多少,最终都会有合适的经理来处理
沿着一条链传递,这就是责任链模式
(下面的表述会沿用这个场景)
3. 源码示例
前端JavaScipt的原型链,也算是一种责任链模式
在JS中,每个对象都有一个原型对象,它可以作为对象的处理者来处理请求,如果当前对象无法处理请求,它会将请求转发给它的原型对象,直到找到一个能够处理请求的对象,如果在整个原型链上都找不到对应的属性或方法,JavaScript会返回undefined
MDN的原型链示例如下:
const o = {
a: 1,
b: 2,
// __proto__ 设置了 [[Prototype]]。它在这里被指定为另一个对象字面量。
__proto__: {
b: 3,
c: 4,
},
};
// o.[[Prototype]] 具有属性 b 和 c。
// o.[[Prototype]].[[Prototype]] 是 Object.prototype(我们会在下文解释其含义)。
// 最后,o.[[Prototype]].[[Prototype]].[[Prototype]] 是 null。
// 这是原型链的末尾,值为 null,
// 根据定义,其没有 [[Prototype]]。
// 因此,完整的原型链看起来像这样:
// { a: 1, b: 2 } ---> { b: 3, c: 4 } ---> Object.prototype ---> null
console.log(o.a); // 1
// o 上有自有属性“a”吗?有,且其值为 1。
console.log(o.b); // 2
// o 上有自有属性“b”吗?有,且其值为 2。
// 原型也有“b”属性,但其没有被访问。
// 这被称为属性遮蔽(Property Shadowing)
console.log(o.c); // 4
// o 上有自有属性“c”吗?没有,检查其原型。
// o.[[Prototype]] 上有自有属性“c”吗?有,其值为 4。
console.log(o.d); // undefined
// o 上有自有属性“d”吗?没有,检查其原型。
// o.[[Prototype]] 上有自有属性“d”吗?没有,检查其原型。
// o.[[Prototype]].[[Prototype]] 是 Object.prototype 且
// 其默认没有“d”属性,检查其原型。
// o.[[Prototype]].[[Prototype]].[[Prototype]] 为 null,停止搜索,
// 未找到该属性,返回 undefined。
DOM事件处理机制可以被看作是一种责任链模式
在DOM中,事件会按照事件冒泡或者事件捕获的方式进行传递和处理,当一个元素上触发了一个事件时,事件会首先经过捕获阶段,然后再经过目标阶段,最后是冒泡阶段。在这个过程中,每个元素都有机会处理事件,如果当前元素无法处理事件,事件会被传递给其父元素,直到document对象
4. 总结
4.1 设计优点
-
开闭原则
无需更改现行制度,添加新的审批人只需告诉前一级经理即可
-
单一职责原则
每一个经理只负责自己能处理的事情
4.2 适用场景
- 请求会被多个处理者处理时,无论是否按照一定的顺序,都可以使用责任链模式
5. 参考资料
[1] 责任链设计模式(职责链模式) (refactoringguru.cn)
[2] 继承与原型链 - JavaScript | MDN (mozilla.org)
标签:__,Prototype,处理,模式,责任,对象,原型,设计模式,属性 From: https://www.cnblogs.com/jiujiubashiyi/p/17894115.html