责任链由多个节点(处理器)组成。在行为上有两种
- (经典责任链模式)遍历链条上的节点,直到找到对应节点,然后处理为止。(基于数组的遍历)
- (变种责任链)由各个节点依次处理,共享负担责任的一部分(通过引用组成链表)
类图

设计一个缓存模块
方案一
- 简单
- 耦合性高
方案二
复杂度很高
经典责任链
Trouble
/*** 问题类**/public class Trouble {private int number;public Trouble(int number){this.number=number;}public int getNumber() {return number;}@Overridepublic String toString() {return "[Trouble "+ number +']';}}
Support
/*** @author chenxinwei* @date 2021/5/17 11:00**/public abstract class Support {private String name;private Support next;public Support(String name) {this.name = name;}protected Support setNext(Support next) {this.next = next;return next;}public Support Support(Support next) {this.next = next;return next;}public final void support(Trouble trouble) {if (resolve(trouble)) {done(trouble);} else if (next != null) {next.support(trouble);} else {fail(trouble);}}protected abstract boolean resolve(Trouble trouble);protected void done(Trouble trouble) {System.out.println(trouble + " is resolved by " + this + " .");}protected void fail(Trouble trouble) {System.out.println(trouble + " cannot be resolved. ");}@Overridepublic String toString() {return "[" + name + "]";}}
LimitSupport
/*** 解决编号小于limit值的问题**/public class LimitSupport extends Support {private int limit;public LimitSupport(String name, int limit) {super(name);this.limit = limit;}@Overrideprotected boolean resolve(Trouble trouble) {if (trouble.getNumber() < limit) {return true;} else {return false;}}}
NoSupport
/*** 永远不解决问题的类**/public class NoSupport extends Support{public NoSupport(String name) {super(name);}@Overrideprotected boolean resolve(Trouble trouble) {return false;}}
OddSupport
/*** 解决奇数编号的问题**/public class OddSupport extends Support {public OddSupport(String name) {super(name);}@Overrideprotected boolean resolve(Trouble trouble) {if (trouble.getNumber() % 2 == 0) {return false;} else {return true;}}}
SpecialSupport
/*** 只解决指定编号的问题**/public class SpecialSupport extends Support {private int number;public SpecialSupport(String name, int number) {super(name);this.number = number;}@Overrideprotected boolean resolve(Trouble trouble) {if (trouble.getNumber() == number) {return true;} else {return false;}}}
类图

解决363号问题的时序图
责任链中的某一个节点负责处理
变种责任链
MyBatis缓存使用Cache实现

链末尾的Cache先执行

MyBatis调用链
责任链每个点处理一种业务
练习
基于以下场景设计一个经典的责任链模式
请假审批流程: 1天以内由HR直接审批,2~3天由部门主管审批,三天以上由经理审批。
