大话设计模式笔记(二十一)の职责链模式

职责链模式

定义

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

UML图

好处

  • 当客户提交一个请求时,请求是沿链传递直至有一个 ConcreteHandler 对象负责处理它
  • 接收者和发送者都没有对方的明确信息,且链中对象自己也并不知道链的结构。结果时职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需要保持他所有的候选者接收者的引用。
  • 可以随时的增加或修改一个请求的结构,增强给对象指派职责的灵活性

但需要注意的是:一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理。

举个栗子

员工申请加薪,需要走流程

Talk is cheap, show me the code

(屁话少说,放码过来)

 1.  /**
 2.   * 管理者
 3.   * Created by callmeDevil on 2019/12/14.
 4.   */
 5.  public abstract class Manager {
 6.  
 7.      protected String name;
 8.      // 上级
 9.      protected Manager superior;
10.  
11.      public Manager(String name){
12.          this.name = name;
13.      }
14.  
15.      // 设置上级
16.      public void setSuperior(Manager superior){
17.          this.superior = superior;
18.      }
19.  
20.      // 申请请求
21.      public abstract void requestApplications(Request request);
22.  
23.  }
24.  
 1.  /**
 2.   * 经理
 3.   * Created by callmeDevil on 2019/12/14.
 4.   */
 5.  public class CommonManager extends Manager {
 6.  
 7.      public CommonManager(String name) {
 8.          super(name);
 9.      }
10.  
11.      @Override
12.      public void requestApplications(Request request) {
13.          // 经理的权限可以批准2天内的假期
14.          if ("请假".equals(request.getRequestType()) && request.getNumber() <= 2) {
15.              System.out.println(String.format("%s : %s 数量%s 被批准", name, request.getRequestContent(), request.getNumber()));
16.          } else {
17.              // 其余申请转交上级
18.              if (superior != null) {
19.                  superior.requestApplications(request);
20.              }
21.          }
22.      }
23.  
24.  }
25.  
 1.  /**
 2.   * 总监
 3.   * Created by callmeDevil on 2019/12/14.
 4.   */
 5.  public class Majordomo extends Manager {
 6.  
 7.      public Majordomo(String name) {
 8.          super(name);
 9.      }
10.  
11.      @Override
12.      public void requestApplications(Request request) {
13.          // 总监的权限可以批准5天内的假期
14.          if ("请假".equals(request.getRequestType()) && request.getNumber() <= 5) {
15.              System.out.println(String.format("%s : %s 数量%s 被批准", name, request.getRequestContent(), request.getNumber()));
16.          } else {
17.              // 其余申请转交上级
18.              if (superior != null) {
19.                  superior.requestApplications(request);
20.              }
21.          }
22.      }
23.  
24.  }
25.  
 1.  /**
 2.   * 总经理
 3.   * Created by callmeDevil on 2019/12/14.
 4.   */
 5.  public class GeneralManager extends Manager {
 6.  
 7.      public GeneralManager(String name) {
 8.          super(name);
 9.      }
10.  
11.      @Override
12.      public void requestApplications(Request request) {
13.          // 总经理可以批准任意天的假期
14.          if ("请假".equals(request.getRequestType())) {
15.              System.out.println(String.format("%s : %s 数量%s 被批准", name, request.getRequestContent(), request.getNumber()));
16.          }
17.          // 加薪在500内,没问题
18.          else if ("加薪".equals(request.getRequestType()) && request.getNumber() <= 500) {
19.              System.out.println(String.format("%s : %s 数量%s 被批准", name, request.getRequestContent(), request.getNumber()));
20.          }
21.          // 加薪超过500要考虑一下
22.          else if ("加薪".equals(request.getRequestType()) && request.getNumber() > 500) {
23.              System.out.println(String.format("%s : %s 数量%s 再说吧", name, request.getRequestContent(), request.getNumber()));
24.          }
25.      }
26.  
27.  }
28.  
 1.  /**
 2.   * 申请类
 3.   * Created by callmeDevil on 2019/12/14.
 4.   */
 5.  public class Request {
 6.  
 7.      // 申请级别
 8.      private String requestType;
 9.      // 申请内容
10.      private String requestContent;
11.      // 数量
12.      private int number;
13.  
14.      // 省略get set
15.  }
16.  
 1.  public class Test {
 2.      public static void main(String[] args) {
 3.          CommonManager commonManager = new CommonManager("中将");
 4.          Majordomo majordomo = new Majordomo("大将");
 5.          GeneralManager generalManager = new GeneralManager("元帅");
 6.          // 设置上级
 7.          commonManager.setSuperior(majordomo);
 8.          majordomo.setSuperior(generalManager);
 9.  
10.          Request request = new Request();
11.          request.setRequestType("请假");
12.          request.setRequestContent("不给请假我不干了");
13.          request.setNumber(1);
14.          commonManager.requestApplications(request); // 客户端的申请都是由经理发起的,但实际上决策是谁,客户端不知道
15.  
16.          Request request2 = new Request();
17.          request2.setRequestType("请假");
18.          request2.setRequestContent("不给请假我不干了");
19.          request2.setNumber(4);
20.          commonManager.requestApplications(request2);
21.  
22.          Request request3 = new Request();
23.          request3.setRequestType("加薪");
24.          request3.setRequestContent("不给加薪我不干了");
25.          request3.setNumber(500);
26.          commonManager.requestApplications(request3);
27.  
28.          Request request4 = new Request();
29.          request4.setRequestType("加薪");
30.          request4.setRequestContent("不给加薪我不干了");
31.          request4.setNumber(1000);
32.          commonManager.requestApplications(request4);
33.      }
34.  }
35.  

运行结果

1.  中将 : 不给请假我不干了 数量1 被批准
2.  大将 : 不给请假我不干了 数量4 被批准
3.  元帅 : 不给加薪我不干了 数量500 被批准
4.  元帅 : 不给加薪我不干了 数量1000 再说吧
5.  
posted @   callmeDevil  阅读(384)  评论(0编辑  收藏  举报
编辑推荐:
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥
点击右上角即可分享
微信分享提示