设计模式 —— 责任链模式

kenticny

今天看到一篇文章中提到了一个设计模式叫做 责任链模式,看起来这个在之前我并没有接触过的设计模式,所以决定查资料学习一下。在学过之后,突然发现虽然没有听过 责任链模式 这个名词,但是在实际工作中,有很多的应用和实现都是符合这个设计模式的。所以在这篇博客中总结一下相关的知识点。

概念

责任链模式 属于设计模式分类中的 行为模式,即对于处理请求的一种设计模式。

责任链模式 具体内容就是定义多个独立的请求处理对象,并且将这些对象链接起来,请求会依次到达每个请求处理对象,请求处理对象可以选择处理或者忽略。

理解

看到上面的概念,不知道首先映入大家脑海的是一个什么样的模型。我首先想到的就是一个“流水线”。记得过去玩过一个小游戏,就是一个传送带上会出现一个蛋糕胚子,然后在第一个步骤会涂上奶油,在第二个步骤会摆上水果,第三个步骤会点缀一些装饰等等。

这个模式就有点 责任链模式 的感觉,假设这是一个真实的蛋糕加工场景,那么客户可能拿着一个蛋糕胚子放入一个加工机器,最后得到一个加工好的蛋糕。在这个过程中,客户不关心中间哪一步做了什么事情,只关心最后的结果。

首先在这个模式中,有一个特点,就是各个处理对象之间都是独立的,所以这就是 责任链模式 的第一个应用场景:解耦合。每个请求处理对象之间完全独立,各自只负责处理各自的功能。

在这个模式中包含三个对象(参考《设计模式》):

  • Handler

  • ConcreteHandler

  • Client

其中 Handler 表示的是请求入口,对应到上面的“蛋糕加工线”的例子中就是客户窗口,放入蛋糕胚子;

然后 ConcreteHandler 表示请求处理对象,对应到上面的例子中,就是每一个步骤,比如第一个步骤涂奶油,第二步摆水果,第三部装饰,这三步就分别代表三个处理对象。

最后 Client 表示的是请求的发出端和结果的接收端,就是上面例子中那个放入蛋糕胚子得到加工好的蛋糕的客户。

应用场景

了解了上面的概念和一些细节的理解,对于应用场景应该不难想到。在平时开发中有很多地方都是基于这个模式进行设计的。比如在使用 Node.js 开发时,使用到的WEB框架 ExpressKoa 中的中间件(middleware)设计。

1
2
3
app.use(middleware.authorize)
app.use(middleware.log)
app.use(middleware.notice)

上述代码展示了在 Node.js 中的中间件设计,这里举例定义了三个中间件,表示了一个HTTP请求进入系统后,首先要经过第一个middleware 授权检查(authorize),然后在第一个 middleware 处理完成以后,如果将请求继续向下传递,则会经过第二个 middleware 日志记录(log),同理,请求会进入第三个 middleware 通知其他系统(notice),最后再进入具体的业务逻辑中处理,在这个过程中,每一个中间件都可以选择中止请求或者将请求继续向下传递。

上面的应用实例是在技术架构层面上的应用,采用中间件(或者叫过滤器)可以以一种低耦合的方式按照一个链式的结构来处理请求。下面再举一个在业务设计上的应用场景。

这个场景其实也是很常见的:审批流程。

在OA系统中,审批流程功能是很常见的,具体的功能就是发起人创建一个需要审批的请求,然后这个请求会在相关的责任人之间流转,在每一个环节中责任人需要完成审批,即通过或者拒绝。这种业务就非常契合 责任链模式

看了上面的两个示例,不知道大家有没有发现,责任链模式 其实和我们编程语言中的 switch ... case ... 模式非常的像。我们使用 switch case 来描述下这个 OA 审批流程:

首先我们定义三个角色,A系统管理员, B系统管理员, C系统管理员。具体业务需求为:一个用户发起审批,根据申请的系统权限分别由对应的系统管理员来审批。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const apply = 'A' // 表示用户申请A权限

switch (apply) {
case 'A':
sysAmanager(apply) // A系统管理员审批
break;
case 'B':
sysBmanager(apply) // B系统管理员审批
break;
case 'C':
sysCmanager(apply) // C系统管理员审批
break;
default:
throw new Error('invalid apply')
}

上述代码描述了一种最简单的审批的过程。可以看出,责任链模式 的应用,其实就是一个顺序执行或者选择执行的流程。所以说 责任链模式 的实现都是可以用 switch case 的方法来表示的。反之亦可以。

总结

责任链模式 作为一种行为模式,可以在开发中帮助我们来作为模块之间的一种解耦方案,同时也增强了请求处理的灵活性,比如我们可以随意根据需求增加或者减少处理对象。如果认真的去看一下,会发现在我们平时的开发中,已经有很多地方都包含了 责任链模式 的影子。

  • 本文标题:设计模式 —— 责任链模式
  • 本文作者:kenticny
  • 创建时间:2016-06-12 21:51:31
  • 本文链接:https://luyun.io/2016/06/12/design-pattern-chain-of-responsibiliy/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论
此页目录
设计模式 —— 责任链模式