Java计划模式 —— 【行为型模式】责任链模式(Chain-of-responsibility Pa ...

打印 上一主题 下一主题

主题 1033|帖子 1033|积分 3099


模式介绍

   责任链模式又名职责链模式,它是一种对象行为的计划模式,为了避免哀求发送者与多个哀求处置处罚者耦合在一起,将所有哀求的处置处罚者通过前一对象记住其下一个对象的引用而连成一条链;当有哀求发生时,可将哀求沿着这条链传递,直到有对象处置处罚它为止。职责链可以是一条直线、一个环链或者是一个树结构的一部分。
  在实际生存中,经常会出现如许的事例:一个哀求有多个对象可以处置处罚,但每个对象的处置处罚条件或权限差别。比方,公司员工告假,可批假的领导有部门负责人、副总司理、总司理等,但每个领导能批准的天数差别,员工必须根据自己要告假的天数去找差别的领导签名,也就是说员工必须记住每个领导的姓名、电话和地址等信息,这增长了难度。如许的例子还有很多,如找领导出差报销、生存中的“伐鼓传花”游戏等。但是使用责任链一级一级传递就会方便很多。

优缺点

1、优点:


  • 低落了对象之间的耦合度: 该模式低落了哀求发送者和接收者的耦合度;
  • 加强了系统的可扩展性: 可以根据必要增长新的哀求处置处罚类,满足开闭原则;
  • 加强了给对象指派职责的灵活性: 当工作流程发生变化,可以动态地改变链内的成员或者修改它们的次序,也可动态地新增或者删除责任;
  • 责任链简化了对象之间的连接: 一个对象只需保持一个指向其后继者的引用,不需保持其他所有处置处罚者的引用,这避免了使用众多的 if 或者 if···else... 语句;
  • 责任分担: 每个类只必要处置处罚自己该处置处罚的工作,不能处置处罚的传递给下一个对象完成,明白各类的责任范围,符合类的单一职责原则。
2、缺点:


  • 不能保证每个哀求肯定被处置处罚。由于一个哀求没有明白的接收者,以是不能保证它肯定会被处置处罚,该哀求可能不停传到链的末了都得不到处置处罚;
  • 对比较长的职责链,哀求的处置处罚可能涉及多个处置处罚对象,系统性能将受到肯定影响;
  • 职责链建立的合理性要靠客户端来保证,增长了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。

适用场景



  • 有多个对象可以处置处罚一个哀求,哪个对象处置处罚该哀求由运行时刻自动确定;
  • 可动态指定一组对象处置处罚哀求,或添加新的处置处罚者;
  • 在不明白指定哀求处置处罚者的环境下,向多个处置处罚者中的一个提交哀求。

模式结构

职责链模式紧张包罗以下角色:


  • 抽象处置处罚者(Handler)角色: 定义一个处置处罚哀求的接口,包罗抽象处置处罚方法和一个后继连接;
  • 具体处置处罚者(Concrete Handler)角色: 实现抽象处置处罚者的处置处罚方法,判断能否处置处罚本次哀求,如果可以处置处罚哀求则处置处罚,否则将该哀求转给它的后继者;
  • 客户类(Client)角色: 创建处置处罚链,并向链头的具体处置处罚者对象提交哀求,它不关心处置处罚细节和哀求的传递过程;


案例实现

现必要开发一个告假流程控制系统。告假1天的只必要小组长同意即可;告假1天到3天的还必要部门司理同意;哀求3天到7天还必要总司理同意才行。
UML类图如下:

抽象处置处罚者角色:
  1. public abstract class Handler {
  2.     protected final static int NUM_ONE = 1;
  3.     protected final static int NUM_THREE = 3;
  4.     protected final static int NUM_SEVEN = 7;
  5.     //该领导处理的请假天数区间
  6.     private int numStart;
  7.     private int numEnd;
  8.     //领导上面还有领导
  9.     private Handler nextHandler;
  10.     //设置请假天数范围
  11.     public Handler(int numStart) {
  12.         this.numStart = numStart;
  13.     }
  14.     //设置请假天数范围
  15.     public Handler(int numStart, int numEnd) {
  16.         this.numStart = numStart;
  17.         this.numEnd = numEnd;
  18.     }
  19.     //设置上级领导
  20.     public void setNextHandler(Handler nextHandler){
  21.         this.nextHandler = nextHandler;
  22.     }
  23.     //各级领导处理请假条方法
  24.     protected abstract void handleLeave(LeaveRequest leave);
  25.     //提交请假条
  26.     public final void submit(LeaveRequest leave){
  27.         //该领导审批
  28.         this.handleLeave(leave);
  29.         if (this.nextHandler != null && leave.getNum() > this.numEnd){
  30.             //提交给上级领导
  31.             this.nextHandler.submit(leave);
  32.         } else {
  33.             System.out.println("流程结束!");
  34.         }
  35.     }
  36. }
复制代码
具体处置处罚者角色【组长、部门司理、总司理】:
  1. public class GroupLeader extends Handler{
  2.     public GroupLeader() {
  3.         super(0, Handler.NUM_ONE);
  4.     }
  5.     @Override
  6.     protected void handleLeave(LeaveRequest leave) {
  7.         System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
  8.         System.out.println("小组长审批:同意。");
  9.     }
  10. }
复制代码
  1. public class Manager extends Handler{
  2.     public Manager() {
  3.         super(Handler.NUM_ONE, Handler.NUM_THREE);
  4.     }
  5.     @Override
  6.     protected void handleLeave(LeaveRequest leave) {
  7.         System.out.println("部门经理审批:同意。");
  8.     }
  9. }
复制代码
  1. public class GeneralManager extends Handler{
  2.     public GeneralManager() {
  3.         super(Handler.NUM_THREE, Handler.NUM_SEVEN);
  4.     }
  5.     @Override
  6.     protected void handleLeave(LeaveRequest leave) {
  7.         System.out.println("总经理审批:同意。");
  8.     }
  9. }
复制代码
哀求【告假条】:
  1. public class LeaveRequest {
  2.     private String name;//姓名
  3.     private int num;//请假天数
  4.     private String content;//请假内容
  5.     public LeaveRequest(String name, int num, String content) {
  6.         this.name = name;
  7.         this.num = num;
  8.         this.content = content;
  9.     }
  10.     public String getName() {
  11.         return name;
  12.     }
  13.     public int getNum() {
  14.         return num;
  15.     }
  16.     public String getContent() {
  17.         return content;
  18.     }
  19. }
复制代码
测试:
  1. public class Client {
  2.     public static void main(String[] args) {
  3.         GroupLeader groupLeader = new GroupLeader();
  4.         Manager manager = new Manager();
  5.         GeneralManager generalManager = new GeneralManager();
  6.         groupLeader.setNextHandler(manager);
  7.         manager.setNextHandler(generalManager);
  8.         LeaveRequest leaveRequest1 = new LeaveRequest("张三", 1, "学习责任链模式");
  9.         groupLeader.submit(leaveRequest1);
  10.         System.out.println("=====================================");
  11.         LeaveRequest leaveRequest2 = new LeaveRequest("张三", 3, "学习责任链模式");
  12.         groupLeader.submit(leaveRequest2);
  13.         System.out.println("=====================================");
  14.         LeaveRequest leaveRequest3 = new LeaveRequest("张三", 7, "学习责任链模式");
  15.         groupLeader.submit(leaveRequest3);
  16.     }
  17. }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

tsx81429

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表