一、职责链模式定义
客户端发送一个请求,请求的接收者被串成一条链,这个请求在这条链上传递,直到链上的某个接收对象能够处理它为止(或者是链上的每一个接收者都会对这个请求作出属于它自己的处理)。
一个请求先经过 A 处理器处理,然后再把请求传递给 B 处理器,B 处理器处理完后再传递给 C 处理器,以此类推,形成一个链条。链条上的每个处理器各自承担各自的处理职责,所以叫作职责链模式。
二、职责链的实现
职责链有两种常见的实现方式,一种是链表方式组织而成的职责链,一种是数组方式组织而成的职责链。但无论是那种方式,职责链中都应该至少存在三类实体:
1. 请求对象(Request 或者 Item),又可以叫成被处理的对象,会被职责链上的处理器处理,经过多个处理器处理后的Request对象里的内容会被改变或者会添加新的内容。
2. 处理器对象(Handler),包含具体的处理逻辑,负责对请求作出处理。
3. 职责链(Chain),作为处理器对象的容器,将多个处理器组织成一个链表或者数组,并且负责请求在处理器之间的传递,将一些流程化的工作从处理器对象解耦出来。
其实请求对象并不需要是一个Object,也可以是一个普通的字符串,或者是一个数组以及任意的结构类型。但是如果将这个被处理的内容封装成一个对象之后,那么这个被处理的内容就能够被规范化,处理器就能清楚的知道它有哪些属性,处理器对这个“被处理的内容”的处理方式也能规范化。
而且,职责链模式对请求对象的处理策略也可以是多变的。它可以是:
1. 职责链中只有1个处理对象能成功处理,其余处理对象需要判断自己能否对请求对象进行处理,如果不能则把这个请求对象往下一个处理器传递;如果发现自己能处理,则处理完之后终止请求的传递。
2. 职责链的每个处理对象能对请求对象作出处理,如果处理成功则往下传递,如果处理失败可以停止传递或者依旧往下传递。
3. 由业务层根据自身需求,自由定义职责链的传递策略,例如如果A处理器处理成功,就跳过B和C处理器,直接转交D处理器处理。这种方式更灵活,但是实现起来也更加复杂。
接下来我们以第一种处理策略来分别实现链表方式和数组方式的职责链模式。
方式一:链表方式
方式二:数组方式
三、职责链模式的应用场景举例
以过滤敏感词为例,对于包含敏感词的内容,我们有两种处理方式,一种是直接禁止发布,另一种是给敏感词打马赛克再发布。这里给出第一种实现方式的代码示例,如下所示:
下面是使用面向过程编写的过滤器代码:
虽然后者看上去更加简单简洁,但是却不易于扩展新的过滤方法,主要体现在两个方面:
一旦扩展新的过滤方法,就要在filter方法中加入逻辑,违反开闭原则;
如果每种过滤方法都是复杂的逻辑,所有过滤方法都堆在SensitiveWordFilter类中,会使得SensitiveWordFilter类过于复杂,不如将每种过滤方法作为一个单独的类,满足单一职责原则减轻代码复杂度。
最后,使用职责链模式可以让客户端灵活的选择使用哪些过滤方式,不使用哪些过滤方式,这是后者无法做到的。