目录

  • 背景
  • 理论
  • 实践
  • 总结

背景

责任链模式,小编在自己项目迭代过程也参与了维护和设计实现;本篇博文主要针对该设计模型进行总结和实践;
简单举例日常生活或者工作中能够接触的责任链模式场景:采购审批流程,请假流程,软件开发中的异常处理流程,web请求处理流程等各种各样的流程;
本文中主要借助比较常见的场景OA请假流程:
作为底层员工的溪源同学发起一个请假申请;
1.当溪源请假天数小于3天时,只需要得到上级主管批准即可;
2.当溪源请假天数大于3天时,主管批准后还需要提交给经理审批即可;
3.当溪源确实有事需要请假超过7天时(比如,度个蜜月啦,哈哈~)那经理审批通过,肯定要进一步提交给总经理审批。

相信这个场景大家应该可以非常轻松的能够理解;
简单的一个流程图如下图:

理论

官方套话

  • 定义:责任链模式(Chain of Responsibility Pattern):避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。职责链模式是一种对象行为型模式。

  • 角色:
    - Handler(抽象处理者):它定义了一个处理请求的接口,一般设计为抽象类,由于不同的具体处理者处理请求的方式不同,因此在其中定义了抽象请求处理方法。因为每一个处理者的下家还是一个处理者,因此在抽象处理者中定义了一个抽象处理者类型的对象,作为其对下家的引用。通过该引用,处理者可以连成一条链。
    - ConcreteHandler(具体处理者):它是抽象处理者的子类,可以处理用户请求,在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在处理请求之前需要进行判断,看是否有相应的处理权限(此处就是基于自己实际业务场景开发实现逻辑) ;
    如果可以处理请求就处理它,否则将请求转发给后继者;在具体处理者中可以访问链中下一个对象,以便请求的转发。

实践

基于上面的角色介绍,溪源先分享出实现的类图,如下:

  • 抽象类:
    顶层抽象处理者类 Handler,维护一个 nextHandler 属性,该属性为当前处理者的下一个处理者的引用;
/** 公共抽象类*/
public abstract class AbstractHandler {/** 抽象父类中可以随意定义子类中共用的变量:定义每个领导允许的请假天数*///为了保证后期审批权限的调整,此处不定义具体天数
//    protected int supervisorDay;
//
//    protected int divisionManagerDay;protected int permissionDay;/** 领导名*/protected String leaderName;public AbstractHandler(int permissionDay, String leaderName) {this.permissionDay = permissionDay;this.leaderName = leaderName;}/** 下一个处理者*/private AbstractHandler nextHandler;public AbstractHandler getNextHandler() {return nextHandler;}public void setNextHandler(AbstractHandler nextHandler) {this.nextHandler = nextHandler;}public String getLeaderName() {return leaderName;}/** 抽象方法,子类实现具体业务逻辑*/public abstract void handleRequest(int day);
}
  • 上级主管
/*** 上级主管处理者*/
public class SupervisorManagerHandler extends AbstractHandler{public SupervisorManagerHandler(int permissionDay, String leaderName) {super(permissionDay, leaderName);}@Overridepublic void handleRequest(int day) {if (day <= permissionDay) {System.out.println("请" + day + "天的假期," + "上级主管:" + getLeaderName() + "审批通过,流程结束");} else {System.out.println("上级主管已同意审批结束,但由于请假天数长,需流转到下一节点处理");getNextHandler().handleRequest(day);}}
}
  • 部门经理
/*** 部门经理处理*/
public class DivisionManagerHandler extends AbstractHandler {public DivisionManagerHandler(int permissionDay, String leaderName) {super(permissionDay, leaderName);}@Overridepublic void handleRequest(int day) {if (day <= permissionDay) {System.out.println("请" + day + "天的假期," + "部门经理:" + getLeaderName() + "审批通过,流程结束");} else {System.out.println("部门经理已同意审批结束,但由于请假天数长,需流转到下一节点处理");getNextHandler().handleRequest(day);}}
}
  • 总经理
/*** 总经理处理*/
public class GeneralManagerHandler extends AbstractHandler{public GeneralManagerHandler(int permissionDay, String leaderName) {super(permissionDay, leaderName);}@Overridepublic void handleRequest(int day) {if (day <= permissionDay) {System.out.println("请" + day + "天的假期," + "总经理:" + getLeaderName() + "审批通过,流程结束");} else {System.out.println("请假时间过长," + "总经理:" +getLeaderName() + "允许你提交辞职流程");
//            getNextHandler().handleRequest(day);}}
}
  • 客户端
public class Client {public static void main(String[] args) {SupervisorManagerHandler supervisorManagerHandler = new SupervisorManagerHandler(3, "张三");DivisionManagerHandler divisionManagerHandler = new DivisionManagerHandler(7, "李四");GeneralManagerHandler generalManagerHandler = new GeneralManagerHandler(10, "夏天");supervisorManagerHandler.setNextHandler(divisionManagerHandler);divisionManagerHandler.setNextHandler(generalManagerHandler);supervisorManagerHandler.handleRequest(50);}
}
  • 运行:
分别从三级单测运行结果如下:
---- 1天:主管审批;
请1天的假期,上级主管:张三审批通过,流程结束Process finished with exit code 0---- 6天:部门经理;
上级主管已同意审批结束,但由于请假天数长,需流转到下一节点处理
请6天的假期,部门经理:李四审批通过,流程结束Process finished with exit code 0---- 10天,总经理;
上级主管已同意审批结束,但由于请假天数长,需流转到下一节点处理
部门经理已同意审批结束,但由于请假天数长,需流转到下一节点处理
请10天的假期,总经理:夏天审批通过,流程结束Process finished with exit code 0---- 20天,不通过辞职;
上级主管已同意审批结束,但由于请假天数长,需流转到下一节点处理
部门经理已同意审批结束,但由于请假天数长,需流转到下一节点处理
请假时间过长,总经理:夏天允许你提交辞职流程

总结

  • 优点:
    1.对象仅需知道该请求会被处理即可,且链中的对象不需要知道链的结构,由客户端负责链的创建,降低了系统的耦合度;
    2.请求处理对象仅需维持一个指向其后继者的引用,而不需要维持它对所有的候选处理者的引用,可简化对象的相互连接;
    3.在给对象分派职责时,职责链可以给我们更多的灵活性,可以在运行时对该链进行动态的增删改,改变处理一个请求的职责;
    4.新增一个新的具体请求处理者时无须修改原有代码,只需要在客户端重新建链即可,符合 “开闭原则”;

  • 缺点:
    1.一个请求可能因职责链没有被正确配置而得不到处理;
    2.对于比较长的职责链,请求的处理可能涉及到多个处理对象,系统性能将受到一定影响,且不方便调试;
    3.可能因为职责链创建不当,造成循环调用,导致系统陷入死循环;

【设计模式系列】行为型之责任链模式相关推荐

  1. Java设计模式之行为型:责任链模式

    背景: 学校规定参加校招的同学必须要请假,且要有相关人员的签字,三天以下需辅导员签字.三到七天需要系主任签字,一个星期以上需要院长签字,更多的则需要校长签字! 上图将学生.辅导员.系主任.院长.校长组 ...

  2. 设计模式笔记十四:责任链模式

    原文:http://www.runoob.com/design-pattern/ 少许个人理解,如有错误请指出.欢迎一起讨论. 责任链模式 顾名思义,责任链模式(Chain of Responsibi ...

  3. 设计模式系列之九:职责链模式

    前言 责任链模式属于行为型设计模式,所谓责任链,就是把责任处理对象连成一条链,这样当一个处理对象不能及时处理的时候就会交给下一个处理对象处理,直到被处理为止.就像我们找人签字盖章的时候,当一个对象不能 ...

  4. 从真实项目中抠出来的设计模式——第三篇:责任链模式

    一:现实场景 有时候在开发的过程中,我们经常会根据某个状态的值,写出很多的ifelse逻辑,比如拿项目里面的案例来说,如果当前发送的是彩信,此种状态需要如何给实体赋值,如果是短信,邮件又是其他方式的赋 ...

  5. 设计模式的C语言应用-责任链模式-第三章

    模式介绍 责任链将需要触发的对象组成一条链,发送者将请求发给链的第一个接收者,并且沿着这条链传递,直到有一个对象来处理它或者直到最后也没有对象处理而留在链末尾端. 图表 1责任链模式流程图 责任链在C ...

  6. 【设计模式】第五章 责任链模式

    第五章 责任链模式 文章目录 第五章 责任链模式 一.介绍 二.结构 三.实现 一.介绍 在现实生活中,一个事件需要经过多个对象处理是很常见的场景.例如,采购审批流程.请假流程等.公司员工请假,可批假 ...

  7. 23种设计模式(11):责任链模式

    定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止. 类型:行为类模式. 类图: 首先来看一段代码: p ...

  8. 《大话设计模式》java实现之责任链模式

    责任链模式各个对象的下一个处理对象在客户端指定,可以自由组合,灵活性强,状态模式各状态则是在编译时设置,即在各状态对象中指定,可对比struts的filter. 另外,书中变量的命名如jingli.z ...

  9. 设计模式学习总结(二十一)--责任链模式

    定义 职责链模式就是避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止. 在职责链模式中我们可以随时随地的增加或者更改一 ...

最新文章

  1. pwa js_如何在互联网信息亭中实现PWA和Barba.js
  2. 360 自动打开word_EXCEL的数据和图表如何与ppt,Word关联,看完你就会了
  3. iOS推送兼容iOS7
  4. JZOJ 5264. 【NOIP2017模拟8.12A组】化学
  5. python求超级素数代码_[宜配屋]听图阁
  6. c++ explicit 修饰构造函数
  7. python编程运算符号-Python中的逻辑运算符
  8. eva每一集片尾曲是谁唱的_求EVA新世纪福音战士的主题曲和片尾曲名字!!
  9. Pycharm(windows)设置中文菜单
  10. 读了王兴一万条饭否,我想送你几十本《王兴的一万条饭否》
  11. 头脑王者源码微信答题小程序pk知识问答源码介绍
  12. 盘点澳洲留学性价比较高城市
  13. 微信小程序Animation动画的使用
  14. juniper认证(JNCIA,JNCIS,JNCIP,JNCIE)介绍
  15. 单侧上行速度测试软件,20210708-确认 低开单边上行,箱体理论几乎是贯穿a股运行周期的,如果平时容易过分看好行情,或者过分看弱行情,不妨就以最中庸的箱体去验证。... - 雪球...
  16. 【前端】页面适配?移动端适配屏幕的各种解决方案!
  17. 基于SABR模型的期权波动率曲线套利策略
  18. lis25ba_实验LIS25BA骨振动传感器采集音频
  19. 一个连接态DRX下的paging接收专利
  20. c语言setfocus作用,C语言FindWindow和SetFocus的问题?

热门文章

  1. #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  2. Windows server 2003 Cpu的-性能报警
  3. Global.asax 文件
  4. spring boot web 开发示例
  5. netty 水位线与oom
  6. 为什么用java开发app_安卓开发为什么选择用Java语言
  7. python http get 请求_Python:编写HTTP Server处理GET请求
  8. netty 常见疑问 faq
  9. Rabbtmq Confirm 确认消息
  10. Redis面试常问2-- 从海量数据里查询某一固定前缀的key? SCAN cursor