一、什么是责任链模式
责任链模式就是某个请求需要多个对象进行处理,从而避免请求的发送者和接收之间的耦合关系。将这些对象连成一条链子,并沿着这条链子传递该请求,直到有对象处理它为止。
责任链模式中的角色:发送者、接受者
责任链模式的流程:
- 发送者知道链中的第一个接受者,它向这个接受者发出请求
- 每一个接受者都对请求进行分析,要么处理它,要么往下传递
- 每一个接受者知道的其他对象只有一个,即它的下家对象
- 如果没有任何接受者处理请求,那么请求将从链上离开,不同的实现对此有不同的反应
二、场景模拟
比如目前有一个开发任务,项目经理(发送者)指派一个任务给开发人员(接受者),但是项目经理是不知道哪个开发人员能不能处理该任务,假设有三个开发人员A/B/C, A接到任务后发现处理不了该任务会往下传给开发B,如果B也处理不了就继续往下传给C,这样一层层传递下去,形成一个链条。
三、传统方式实现
// 任务类(发送者)
class Assign {
constructor(task) {
// 任务名称
this.task = task
}
}
// 接受任务的类
class WorkFlow {
constructor(assign) {
// 发送者
this.assign = assign
}
handler(executorArr) {
// 循环处理者数组,查找哪个处理者能做该任务
executorArr.forEach(item => {
if (this.assign.task == item.task) {
return item.start()
}
})
return;
}
}
// 处理者(接收者)
class Executor {
constructor(name, task) {
// 接受者姓名
this.name = name
// 接受者能处理的任务
this.task = task
}
// 去做任务
start() {
console.log(`${this.name}去做:${this.task}`)
}
}
// 实例化处理对象
const C = new Executor('王五', 'SQL优化任务')
const B = new Executor('李四', 'PHP开发任务')
const A = new Executor('张三', 'javascript开发任务')
// 实例化任务对象
// 发送者分配一个 javascript开发任务
const assign = new Assign('SQL优化任务')
// 实例化接收任务类,传递任务下去
const workflow = new WorkFlow(assign)
workflow.handler([A, B, C])
四、责任链模式实现
// 任务类(发送者)
class Assign {
constructor(task) {
// 任务名称
this.task = task
}
}
// 接受任务的类
class WorkFlow {
constructor(assign) {
// 发送者
this.assign = assign
}
// 处理接收对象,传递给下一个接收对象
handler(executor) {
// 如果第一个处理者能处理,直接处理任务
if (this.assign.task == executor.task) {
return executor.start()
} else {
// 否则继续传递到下一个处理者去处理
this.handler(executor.successtor)
}
// 如果都没处理者能处理,返回空
return;
}
}
// 处理者(接收者)
class Executor {
constructor(name, task, successtor) {
// 接受者姓名
this.name = name
// 接受者能处理的任务
this.task = task
// 下一个处理者的引用
this.successtor = successtor
}
// 去做任务
start() {
console.log(`${this.name}去做:${this.task}`)
}
}
// 实例化处理对象
const C = new Executor('王五', 'SQL优化任务')
const B = new Executor('李四', 'PHP开发任务', C)
const A = new Executor('张三', 'javascript开发任务', B)
// 实例化任务对象
// 发送者分配一个 javascript开发任务
const assign = new Assign('javascript开发任务')
// 实例化接收任务类,传递任务下去
const workflow = new WorkFlow(assign)
workflow.handler(A)
五、总结
使用场景: 经过上面的例子,我们发现责任链模式比较适合比如一个任务需要多个对象才能完成处理的情况或者代码存在许多if-else判断的情况,例如OA事件审批、分配开发任务等。
优缺点: 降低了请求的发送者和接受者之间的耦合、分工明确、代码更加清晰。但同时需要层层传递下去寻找能处理任务的接受者,所有的判定条件都要执行一遍,链条过长时,可能存在性能问题。