简介
责任链模式(Chain of Responsibility Pattern)使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
实例
责任链模式包含一下角色:
Handler
: 抽象处理者。定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。ConcreteHandler
:具体处理者。具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。Client
:客户类
下面我们以一个简单的请假作为示例。假设请假一天,项目经理处理就能处理,三天之类归项目总监处理,七天内归老板处理,请假不允许超过七天。 抽象处理者
public abstract class AbstractHandler { /** * 下一个处理对象 */ private AbstractHandler next; /** * 处理请假 * * @param leaveDays 天数 * @return 处理结果 */ public final String handleLeave(int leaveDays) { if (this.getLeaveDays() >= leaveDays) { return this.handle(); } else { if (Objects.nonNull(next)) { return next.handleLeave(leaveDays); } else { return "大老板都不能处理你的假期了~~"; } } } /** * 具体处理 * * @return 处理结果 */ protected abstract String handle(); /** * 每个处理类能处理的天数,数据可以使数据库获取,这里简单就写死了 * * @return 请假天数 */ protected abstract Integer getLeaveDays(); /** * 设置下一个处理类 * * @param next */ public void setNext(AbstractHandler next) { this.next = next; }}复制代码
具体处理者
// 项目经理处理public class PMHandler extends AbstractHandler { @Override protected String handle() { return "你的请假被项目经理处理了"; } @Override protected Integer getLeaveDays() { return 1; }}// 项目总监处理public class PDHandler extends AbstractHandler { @Override protected String handle() { return "你的请假被项目总监处理了"; } @Override protected Integer getLeaveDays() { return 3; }}// 大老板处理public class BossHandler extends AbstractHandler { @Override protected String handle() { return "你的请假被大老板处理了"; } @Override protected Integer getLeaveDays() { return 7; }}复制代码
客户端
@Testpublic void test() { PMHandler pmHandler = new PMHandler(); PDHandler pdHandler = new PDHandler(); BossHandler bossHandler = new BossHandler(); pmHandler.setNext(pdHandler); pdHandler.setNext(bossHandler); String leaveRes = pmHandler.handleLeave(1); System.out.println(leaveRes); String leaveRes1 = pmHandler.handleLeave(3); System.out.println(leaveRes1); String leaveRes2 = pmHandler.handleLeave(7); System.out.println(leaveRes2); String leaveRes3 = pmHandler.handleLeave(8); System.out.println(leaveRes3);}复制代码
类图
优点
- 降低耦合度。它将请求的发送者和接收者解耦;
- 简化了对象。使得对象不需要知道链的结构;
- 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任;
- 增加新的请求处理类很方便。
缺点
- 请求没有明确的接收者,不能保证它一定会被处理,该请求可能一直到链的末端都得不到处理;
- 对于比较长的职责链,请求的处理可能涉及到多个处理对象,系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
适用场景
- 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定;
- 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求;
- 可动态指定一组对象处理请求。
总结
责任链模式有两种使用形式:纯责任链模式和不纯的责任链模式。
如果一个类要么承担责任处理请求要么将请求踢给下一个皮球,则被称为纯责任链模式;如果一个类承担了一部分责任,还将请求踢给下一个皮球,则被称为不纯的责任链模式。纯的责任链模式的实际例子很难找到,一般看到的例子均是不纯的责任链模式的实现。