目录
为了避免请求发送者和多个请求处理者耦合在一起,就将所有请求处理者通过前一个对象记住下一个对象的引用的方式形成一条链;当有请求到来时,可以将请求沿着这条链传递,知道有对象能处理他为止.
例如,公司员工请假,可以批假的领导有小组组长、部门经理、总经理,但是每个领导比准的天数不同,那么员工请假时,就需要记住每一个领导的能请假的天数,十分不方便,但是通过责任链模式,你就可以直接把假条先交给能处理天数最少的人即可,如果小组组长处理不了,小组组长因为持有 部门经理 的引用,就可以找到他,让他处理..... 以此类推,直到找到能处理这个假条的领导为止.
责任链模式主要包含以下角色:
实现上述案例.
- /**
- * 请假条类
- */
- public class LeaveRequest {
-
- //请假人姓名
- private String name;
- //请假天数
- private int num;
- //请假原因
- private String reason;
-
- public LeaveRequest(String name, int num, String reason) {
- this.name = name;
- this.num = num;
- this.reason = reason;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public int getNum() {
- return num;
- }
-
- public void setNum(int num) {
- this.num = num;
- }
-
- public String getReason() {
- return reason;
- }
-
- public void setReason(String reason) {
- this.reason = reason;
- }
-
- }
- /**
- * 抽象处理者
- */
- public abstract class Handler {
-
- //请假天数
- protected static final int ONE_DAY = 1;
- protected static final int THREE_DAY = 3;
- protected static final int SEVEN_DAY = 7;
-
- //各级领导能处理请假天数区间
- private int numStart;
- private int numEnd;
-
- //领导的领导
- private Handler nextHandler;
-
- /**
- * 领导处理请假天数区间
- * @param numStart
- * @param numEnd
- */
- public Handler(int numStart, int numEnd) {
- this.numStart = numStart;
- this.numEnd = numEnd;
- }
-
- public void setNextHandler(Handler nextHandler) {
- this.nextHandler = nextHandler;
- }
-
- /**
- * 提交请假请求
- */
- public final void submit(LeaveRequest request) {
- if(request.getNum() <= numEnd) {
- this.handlerLeave(request);
- } else if(this.nextHandler != null) {
- nextHandler.submit(request);
- } else {
- System.out.println("请假天数超过上限!");
- }
- }
-
- protected abstract void handlerLeave(LeaveRequest request);
-
- }
- /**
- * 具体处理者: 小组组长
- */
- public class GroupLeader extends Handler {
-
- /**
- * 小组长所能处理的请假天数区间
- */
- public GroupLeader() {
- super(0, ONE_DAY);
- }
-
- @Override
- protected void handlerLeave(LeaveRequest request) {
- System.out.println(request.getName() + "请假 " + request.getNum() + " 天," +
- request.getReason());
- System.out.println("小组长审批通过");
- }
-
- }
- /**
- * 具体处理者: 部门经理
- */
- public class Manager extends Handler {
-
- /**
- * 经理所能处理的请假天数区间
- */
- public Manager() {
- super(ONE_DAY, THREE_DAY);
- }
-
- @Override
- protected void handlerLeave(LeaveRequest request) {
- System.out.println(request.getName() + "请假 " + request.getNum() + " 天," +
- request.getReason());
- System.out.println("部门经理审批通过");
- }
-
- }
- /**
- * 具体处理者: 总经理
- */
- public class GeneralManager extends Handler {
-
- /**
- * 经理所能处理的请假天数区间
- */
- public GeneralManager() {
- super(THREE_DAY, SEVEN_DAY);
- }
-
- @Override
- protected void handlerLeave(LeaveRequest request) {
- System.out.println(request.getName() + "请假 " + request.getNum() + " 天," +
- request.getReason());
- System.out.println("总经理审批通过");
- }
-
- }
- /**
- * 客户类
- */
- public class Client {
-
- public static void main(String[] args) {
- //1.假条
- LeaveRequest request1 = new LeaveRequest("李白", 1, "这几天要出诗集~");
- LeaveRequest request2 = new LeaveRequest("杜甫", 3, "生病了,身体不适~");
- LeaveRequest request3 = new LeaveRequest("龙洋静", 6, "着急结婚!");
-
- //2.责任链关系
- GroupLeader groupLeader = new GroupLeader();
- Manager manager = new Manager();
- GeneralManager generalManager = new GeneralManager();
-
- groupLeader.setNextHandler(manager);
- manager.setNextHandler(generalManager);
-
- //3.提交假条
- groupLeader.submit(request1);
- System.out.println("===============");
- groupLeader.submit(request2);
- System.out.println("===============");
- groupLeader.submit(request3);
- }
-
- }
执行结果如下:

优点:
缺点:
不能保证每一个请求一定被处理:因为请求没有明确的接收者,因此不能保证他一定被处理,该请求可能传到链末也得不到处理.
性能影响:如果责任链较长,请求的处理可能涉及到多个对象,性能会有所损耗.
复杂度:责任链的合理性全靠客户端来保证,增加了客户端的复杂度.
1. 多个对象可以处理同一个请求,但具体由哪个对象处理则在运行时动态决定.
2. 请求者不明确要对哪一个对象进行提交申请.
例如像公司职级审批流的设定.
例如用户找回密码需要一步步校验的密保信息.
