模拟生活
假设Tony请假,小于2天,直属领导签字,大于2天小于5天直属领导签字,部门总监签字,提交行政,多于5天小于一个月,直属领导签字,部门总监签字,CEO签字,提交行政。
代码
from abc import ABCMeta, abstractmethodclass Request:"""请求(内容)"""def __init__(self, name, day_off, reason):self.__name = nameself.__day_off = day_offself.__reason = reasondef get_name(self):return self.__namedef get_day_off(self):return self.__day_offdef get_reason(self):return self.__reasonclass Responsible(metaclass=ABCMeta):"""责任人抽象类"""def __init__(self, name, title):self.__name = nameself.__title = titleself._next_handler = Nonedef get_name(self):return self.__namedef get_title(self):return self.__titledef set_next_handle(self, next_handle):self._next_handler = next_handledef get_next_handle(self):return self._next_handlerdef 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 = nameself.__leader = Nonedef set_name(self, name):self.__name = namedef get_name(self):return self.__namedef set_leader(self, leader):self.__leader = leaderdef get_leader(self):return self.__leaderdef 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 />责任人可自由组合: 责任链上的责任人可以根据业务的具体逻辑进行自由组合和排序。
职责模式的优缺点
优点
降低耦合度。它将请求的发送者和接收者解耦
简化对象。它使的对象不需要知道链的结构
增强给对象指派职责的灵活性。可以改变链内的成员或者调动它们的次序,允许动态新增和删除责任人。
增加新的处理类很方便
缺点
不能保证请求一定被接收
系统性能将受到一定的影响,而且在进行代码调试时不太方便,可能会造成循环调用
应用场景
有多个对象可以处理同一个请求,具体那个对象处理该请求在运行时刻自动确定
请求处理具有明显的一层层传递关系
请求的处理流程和顺序需要程序运行时动态确定
常见的审批流程
