Chain of Responsibility
责任链模式:为了避免请求发送者和请求处理者耦合在一起,于是将宿友的请求的处理者通过前一对象记住其下一对象的引用而形成一条链;当由请求发生时,可讲请求沿着这条链进行传递,知道对象处理它为止。也被称为 职责链模式
最能体现责任链模式当属审批流程, 我们在审批的时候,经常会根据条件来判断是否能审批或者是否应该由下一级来审批, 比如:请假3天以内由直属领导审批,3-7天由部门经理审批等等。责任链模式可以动态的组装审批流程,按照一定的条件执行。
其UML图如下:
image.png

1、场景描述

请假审批流程

  • 3天以内:直属领导
  • 3-7天:部门经理
  • 7天以上:总监

用责任链模式代码实现。

2、实现

  1. /// <summary>
  2. /// 抽象处理者-抽象领导
  3. /// </summary>
  4. public abstract class AbstractLeader
  5. {
  6. // 下一审判者
  7. protected readonly AbstractLeader _next;
  8. public AbstractLeader(AbstractLeader next)
  9. {
  10. this._next = next;
  11. }
  12. /// <summary>
  13. /// 审批
  14. /// </summary>
  15. public abstract void Approve(int days);
  16. }
  17. /// <summary>
  18. /// 具体处理者: 直属领导
  19. /// </summary>
  20. public class DirectLeader : AbstractLeader
  21. {
  22. public DirectLeader(AbstractLeader next) : base(next)
  23. {
  24. }
  25. /// <summary>
  26. /// 审批
  27. /// </summary>
  28. /// <param name="days"></param>
  29. /// <exception cref="NotImplementedException"></exception>
  30. public override void Approve(int days)
  31. {
  32. if (days < 3)
  33. Console.WriteLine("直属领导审批通过...");
  34. else if (_next != null)
  35. _next.Approve(days);
  36. else
  37. Console.WriteLine("审批不通过...");
  38. return;
  39. }
  40. }
  41. /// <summary>
  42. /// 具体处理者:部门经理
  43. /// </summary>
  44. public class Manager : AbstractLeader
  45. {
  46. public Manager(AbstractLeader next) : base(next)
  47. {
  48. }
  49. public override void Approve(int days)
  50. {
  51. if (days >= 3 && days < 7)
  52. Console.WriteLine("部门经理审批通过...");
  53. else if (_next != null)
  54. _next.Approve(days);
  55. else
  56. Console.WriteLine("审批不通过...");
  57. return;
  58. }
  59. }
  60. /// <summary>
  61. /// 具体处理者:总监
  62. /// </summary>
  63. public class RDDiretor : AbstractLeader
  64. {
  65. public RDDiretor(AbstractLeader next) : base(next)
  66. {
  67. }
  68. public override void Approve(int days)
  69. {
  70. if (days > 7)
  71. Console.WriteLine("总监审批通过...");
  72. else if (_next != null)
  73. _next.Approve(days);
  74. else
  75. Console.WriteLine("审批不通过...");
  76. return;
  77. }
  78. }
  79. // 客户端
  80. // 组装责任链
  81. AbstractLeader director = new RDDiretor(null);
  82. AbstractLeader manager = new Manager(director);
  83. AbstractLeader leader = new DirectLeader(manager);
  84. // 调用
  85. leader.Approve(2);
  86. Console.WriteLine("*********************");
  87. leader.Approve(5);
  88. Console.WriteLine("*********************");
  89. leader.Approve(8);

3、优缺点

优点:

  • 每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则
  • 增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则
  • 可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任

缺点:

  • 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用

    4、应用场景

  • 一个系统的审批需要多个对象才能完成处理的情况下,例如请假系统等。

  • 代码中存在多个if-else语句的情况下,此时可以考虑使用责任链模式来对代码进行重构。