模拟生活
假设Tony请假,小于2天,直属领导签字,大于2天小于5天直属领导签字,部门总监签字,提交行政,多于5天小于一个月,直属领导签字,部门总监签字,CEO签字,提交行政。
代码
from abc import ABCMeta, abstractmethod
class Request:
"""请求(内容)"""
def __init__(self, name, day_off, reason):
self.__name = name
self.__day_off = day_off
self.__reason = reason
def get_name(self):
return self.__name
def get_day_off(self):
return self.__day_off
def get_reason(self):
return self.__reason
class Responsible(metaclass=ABCMeta):
"""责任人抽象类"""
def __init__(self, name, title):
self.__name = name
self.__title = title
self._next_handler = None
def get_name(self):
return self.__name
def get_title(self):
return self.__title
def set_next_handle(self, next_handle):
self._next_handler = next_handle
def get_next_handle(self):
return self._next_handler
def handle_request(self, request):
self._handle_request_impl(request=request)
if self._next_handler is not None:
self._next_handler.handle_request(request)
def _handle_request_impl(self, request):
"""正在处理请求的方法"""
class Person:
"""请假人"""
def __init__(self, name):
self.__name = name
self.__leader = None
def set_name(self, name):
self.__name = name
def get_name(self):
return self.__name
def set_leader(self, leader):
self.__leader = leader
def get_leader(self):
return self.__leader
def send_request(self, request):
print("%s 申请请假 %s 天。 请假事由: %s" % (request.get_name(), request.get_day_off(), request.get_reason()))
if self.__leader is not None:
self.__leader.handle_request(request)
class Supervisor(Responsible):
def __init__(self, name, title):
super().__init__(name=name, title=title)
def _handle_request_impl(self, request):
if request.get_day_off() <= 2:
print("同意 %s 请假, 签字人: %s(%s)" % (request.get_name(), self.get_name(), self.get_title()))
class DepartmentManager(Responsible):
def __init__(self, name, title):
super().__init__(name=name, title=title)
def _handle_request_impl(self, request):
if 2 < request.get_day_off() <= 5:
print("同意 %s 请假, 签字人: %s(%s)" % (request.get_name(), self.get_name(), self.get_title()))
class CEO(Responsible):
def __init__(self, name, title):
super().__init__(name=name, title=title)
def _handle_request_impl(self, request):
if 5 < request.get_day_off() <= 22:
print("同意 %s 请假, 签字人: %s(%s)" % (request.get_name(), self.get_name(), self.get_title()))
class Administrator(Responsible):
def __init__(self, name, title):
super().__init__(name=name, title=title)
def _handle_request_impl(self, request):
print("%s 请求申请已审核,情况属实!已备案。处理人: %s(%s)\n" % (request.get_name(), self.get_name(), self.get_title()))
def test():
direct_leader = Supervisor("Eren", "客户端研发部经理")
department_leader = DepartmentManager("Eric", "技术研发中心总监")
ceo = CEO("Helen", "创新文化公司CEO")
administrator = Administrator("Nina", "行政中心总监")
direct_leader.set_next_handle(department_leader)
department_leader.set_next_handle(ceo)
ceo.set_next_handle(administrator)
sunny = Person("Sunny")
sunny.set_leader(direct_leader)
sunny.send_request(Request(sunny.get_name(), 1, "参加MDCC大会"))
tony = Person("Tony")
tony.set_leader(direct_leader)
tony.send_request(Request(tony.get_name(), 5, "回家有事"))
pony = Person("Pony")
pony.set_leader(direct_leader)
pony.send_request(Request(pony.get_name(), 15, "出国深造"))
if __name__ == '__main__':
test()
什么是职责模式
职责模式也称为责任链模式,它将请求的发送者和接受者解耦。客户端不需要知道请求处理者的明确信息和处理的具体逻辑,甚至不需要知道链的结构,它只需要将请求进行发送即可。
职责模式设计思想
在故事剧情中,对于Tony来说,他并不需要知道请假条的处理的具体细节,甚至不需要知道请假条去哪里了,他只需要知道请假条有人会处理,而假条的处理流程是一手接一手的责任传递,处理假条的所有人构成一条责任的链条,链条上的每个人只会处理自己职责范围内的请求,对于自己处理不了的请求,直接交给下一个负责人。这就是程序设计中职责模式的核心思想。
在职责模式中我们可以随时随地增加或者更改责任人,甚至可以更改责任人的顺序,增加系统的灵活性。但是有时候可能会导致一个请求无论如何也得不到处理,它放置到链条的末端。
模型说明
1.设计要点
请求者与请求内容:确认谁要发送请求,发送请求的对象称为请求者。请求的内容通过发送请求时的参数进行传递。<br />有哪些责任人: 责任人是构成责任链的关键要素。请求的流动方向是链条中的线,而责任人则是链条上的点,线和点共同构成链。<br />对责任人抽象:真实世界中的责任人多种多样,纷繁复杂,有不同的职责和功能;但他们也有一个共同的特征,都可以处理请求。所以需要对责任人进行抽象,使他们具有责任的可传递性。<br />责任人可自由组合: 责任链上的责任人可以根据业务的具体逻辑进行自由组合和排序。
职责模式的优缺点
优点
降低耦合度。它将请求的发送者和接收者解耦
简化对象。它使的对象不需要知道链的结构
增强给对象指派职责的灵活性。可以改变链内的成员或者调动它们的次序,允许动态新增和删除责任人。
增加新的处理类很方便
缺点
不能保证请求一定被接收
系统性能将受到一定的影响,而且在进行代码调试时不太方便,可能会造成循环调用
应用场景
有多个对象可以处理同一个请求,具体那个对象处理该请求在运行时刻自动确定
请求处理具有明显的一层层传递关系
请求的处理流程和顺序需要程序运行时动态确定
常见的审批流程