模拟生活

假设Tony请假,小于2天,直属领导签字,大于2天小于5天直属领导签字,部门总监签字,提交行政,多于5天小于一个月,直属领导签字,部门总监签字,CEO签字,提交行政。

代码

  1. from abc import ABCMeta, abstractmethod
  2. class Request:
  3. """请求(内容)"""
  4. def __init__(self, name, day_off, reason):
  5. self.__name = name
  6. self.__day_off = day_off
  7. self.__reason = reason
  8. def get_name(self):
  9. return self.__name
  10. def get_day_off(self):
  11. return self.__day_off
  12. def get_reason(self):
  13. return self.__reason
  14. class Responsible(metaclass=ABCMeta):
  15. """责任人抽象类"""
  16. def __init__(self, name, title):
  17. self.__name = name
  18. self.__title = title
  19. self._next_handler = None
  20. def get_name(self):
  21. return self.__name
  22. def get_title(self):
  23. return self.__title
  24. def set_next_handle(self, next_handle):
  25. self._next_handler = next_handle
  26. def get_next_handle(self):
  27. return self._next_handler
  28. def handle_request(self, request):
  29. self._handle_request_impl(request=request)
  30. if self._next_handler is not None:
  31. self._next_handler.handle_request(request)
  32. def _handle_request_impl(self, request):
  33. """正在处理请求的方法"""
  34. class Person:
  35. """请假人"""
  36. def __init__(self, name):
  37. self.__name = name
  38. self.__leader = None
  39. def set_name(self, name):
  40. self.__name = name
  41. def get_name(self):
  42. return self.__name
  43. def set_leader(self, leader):
  44. self.__leader = leader
  45. def get_leader(self):
  46. return self.__leader
  47. def send_request(self, request):
  48. print("%s 申请请假 %s 天。 请假事由: %s" % (request.get_name(), request.get_day_off(), request.get_reason()))
  49. if self.__leader is not None:
  50. self.__leader.handle_request(request)
  51. class Supervisor(Responsible):
  52. def __init__(self, name, title):
  53. super().__init__(name=name, title=title)
  54. def _handle_request_impl(self, request):
  55. if request.get_day_off() <= 2:
  56. print("同意 %s 请假, 签字人: %s(%s)" % (request.get_name(), self.get_name(), self.get_title()))
  57. class DepartmentManager(Responsible):
  58. def __init__(self, name, title):
  59. super().__init__(name=name, title=title)
  60. def _handle_request_impl(self, request):
  61. if 2 < request.get_day_off() <= 5:
  62. print("同意 %s 请假, 签字人: %s(%s)" % (request.get_name(), self.get_name(), self.get_title()))
  63. class CEO(Responsible):
  64. def __init__(self, name, title):
  65. super().__init__(name=name, title=title)
  66. def _handle_request_impl(self, request):
  67. if 5 < request.get_day_off() <= 22:
  68. print("同意 %s 请假, 签字人: %s(%s)" % (request.get_name(), self.get_name(), self.get_title()))
  69. class Administrator(Responsible):
  70. def __init__(self, name, title):
  71. super().__init__(name=name, title=title)
  72. def _handle_request_impl(self, request):
  73. print("%s 请求申请已审核,情况属实!已备案。处理人: %s(%s)\n" % (request.get_name(), self.get_name(), self.get_title()))
  74. def test():
  75. direct_leader = Supervisor("Eren", "客户端研发部经理")
  76. department_leader = DepartmentManager("Eric", "技术研发中心总监")
  77. ceo = CEO("Helen", "创新文化公司CEO")
  78. administrator = Administrator("Nina", "行政中心总监")
  79. direct_leader.set_next_handle(department_leader)
  80. department_leader.set_next_handle(ceo)
  81. ceo.set_next_handle(administrator)
  82. sunny = Person("Sunny")
  83. sunny.set_leader(direct_leader)
  84. sunny.send_request(Request(sunny.get_name(), 1, "参加MDCC大会"))
  85. tony = Person("Tony")
  86. tony.set_leader(direct_leader)
  87. tony.send_request(Request(tony.get_name(), 5, "回家有事"))
  88. pony = Person("Pony")
  89. pony.set_leader(direct_leader)
  90. pony.send_request(Request(pony.get_name(), 15, "出国深造"))
  91. if __name__ == '__main__':
  92. test()

什么是职责模式

职责模式也称为责任链模式,它将请求的发送者和接受者解耦。客户端不需要知道请求处理者的明确信息和处理的具体逻辑,甚至不需要知道链的结构,它只需要将请求进行发送即可。

职责模式设计思想

在故事剧情中,对于Tony来说,他并不需要知道请假条的处理的具体细节,甚至不需要知道请假条去哪里了,他只需要知道请假条有人会处理,而假条的处理流程是一手接一手的责任传递,处理假条的所有人构成一条责任的链条,链条上的每个人只会处理自己职责范围内的请求,对于自己处理不了的请求,直接交给下一个负责人。这就是程序设计中职责模式的核心思想。
在职责模式中我们可以随时随地增加或者更改责任人,甚至可以更改责任人的顺序,增加系统的灵活性。但是有时候可能会导致一个请求无论如何也得不到处理,它放置到链条的末端。

模型说明

1.设计要点

  1. 请求者与请求内容:确认谁要发送请求,发送请求的对象称为请求者。请求的内容通过发送请求时的参数进行传递。<br />有哪些责任人: 责任人是构成责任链的关键要素。请求的流动方向是链条中的线,而责任人则是链条上的点,线和点共同构成链。<br />对责任人抽象:真实世界中的责任人多种多样,纷繁复杂,有不同的职责和功能;但他们也有一个共同的特征,都可以处理请求。所以需要对责任人进行抽象,使他们具有责任的可传递性。<br />责任人可自由组合: 责任链上的责任人可以根据业务的具体逻辑进行自由组合和排序。

职责模式的优缺点

优点

降低耦合度。它将请求的发送者和接收者解耦
简化对象。它使的对象不需要知道链的结构
增强给对象指派职责的灵活性。可以改变链内的成员或者调动它们的次序,允许动态新增和删除责任人。
增加新的处理类很方便

缺点

不能保证请求一定被接收
系统性能将受到一定的影响,而且在进行代码调试时不太方便,可能会造成循环调用

应用场景

有多个对象可以处理同一个请求,具体那个对象处理该请求在运行时刻自动确定
请求处理具有明显的一层层传递关系
请求的处理流程和顺序需要程序运行时动态确定
常见的审批流程