一、定义
职责链模式,就是将能够处理某类请求事件的一些处理类,类似链条的串联起来。请求在链条上处理的时候,并不知道具体是哪个处理类进行处理的。一定程度上实现了请求和处理的解耦。
实际生活中的经典例子就是公司的报销流程,一般主管、经理、总经理都是不同的报销额度,当职员进行报销申请的时候,如果主管权限不足,会自动的再向上提交给经理,经理可以处理也可以再向上
提交总经理。报销申请(请求事件)提交后,职员自己并不需要再关注谁能处理,只是关注到最后结果即可。
二、java代码示例
示例中,就以简单的逐层报销为例子:
申请请求类:
1 package com.cfang.chainTest; 2 3 import lombok.Builder; 4 import lombok.Data; 5 6 @Data 7 @Builder 8 public class ApplyFile { 9 10 private String name; 11 private Integer money; 12 13 }
抽象处理类:
1 package com.cfang.chainTest; 2 3 import lombok.Data; 4 import lombok.NonNull; 5 6 @Data 7 public abstract class HandleCls { 8 9 protected HandleCls nextCls; 10 @NonNull 11 private String name; //处理节点名 12 13 public abstract void pro(ApplyFile applyFile); 14 }
主管类(直接审批,负责接收和向上申请)
1 package com.cfang.chainTest; 2 3 public class ZhuGuan extends HandleCls{ 4 5 public ZhuGuan(String name) { 6 super(name); 7 } 8 @Override 9 public void pro(ApplyFile applyFile) { 10 if(applyFile.getMoney() < 100) { 11 System.out.println(this.getName() + "处理了申请:" + applyFile.toString()); 12 }else { 13 this.nextCls.pro(applyFile); 14 } 15 } 16 17 }
经理类:
1 package com.cfang.chainTest; 2 3 public class JingLi extends HandleCls{ 4 5 public JingLi(String name) { 6 super(name); 7 } 8 @Override 9 public void pro(ApplyFile applyFile) { 10 if(applyFile.getMoney() < 200) { 11 System.out.println(this.getName() + "处理了申请:" + applyFile.toString()); 12 }else { 13 this.nextCls.pro(applyFile); 14 } 15 } 16 17 }
总经理类:
扫描二维码关注公众号,回复:
6532737 查看本文章
1 package com.cfang.chainTest; 2 3 public class ZoneJingLi extends HandleCls{ 4 5 public ZoneJingLi(String name) { 6 super(name); 7 } 8 @Override 9 public void pro(ApplyFile applyFile) { 10 if(applyFile.getMoney() < 300) { 11 System.out.println(this.getName() + "处理了申请:" + applyFile.toString()); 12 }else { 13 this.nextCls.pro(applyFile); 14 } 15 } 16 17 }
测试类:审批流程链条是自己进行设置的,供使用者进行调用。
1 package com.cfang.chainTest; 2 3 public class TestMain { 4 5 public static void main(String[] args) { 6 //创建职责链条 7 HandleCls p1 = new ZhuGuan("主管"); 8 HandleCls p2 = new JingLi("经理"); 9 HandleCls p3 = new ZoneJingLi("总经理"); 10 p1.setNextCls(p2); 11 p2.setNextCls(p3); 12 13 //创建报销申请 14 ApplyFile applyFile = ApplyFile.builder().name("猪小屁").money(99).build(); 15 p1.pro(applyFile); 16 17 applyFile = ApplyFile.builder().name("猪小屁").money(101).build(); 18 p1.pro(applyFile); 19 20 applyFile = ApplyFile.builder().name("猪小屁").money(201).build(); 21 p1.pro(applyFile); 22 } 23 }
输出:
主管处理了申请:ApplyFile(name=猪小屁, money=99) 经理处理了申请:ApplyFile(name=猪小屁, money=101) 总经理处理了申请:ApplyFile(name=猪小屁, money=201)
三、实际应用场景
java类加载机制、servlet filter过滤器链、mybatis的plugin机制。。。
四、总结
优点:
1、请求对象不需要具体知道哪个类去处理,只需要关注最后处理结果即可。
2、新增一个处理类的时候,无需修改原有代码,只需要维护处理器链即可
缺点:
1、调用的时候,不明确一定能处理,可能会出现到最后都没处理(一般可以设计个兜底服务)
2、建立链条的时候,如果设置不当,可能形成循环调用。