[Python设计模式] 第24章 加薪审批——职责链模式

it2022-05-21  67

github地址:https://github.com/cheesezh/python_design_patterns

题目

用程序模拟以下情景

员工向经理发起加薪申请,经理无权决定,需要向总监汇报,加薪额度超过总监权力范围,需要向总经理汇报;员工还可以提交请加申请,经理可以决定2天以下的假,总监可以决定5天以下的假,其余都要上报总经理;

基础版本

class Request(): def __init__(self): self.type = None # 申请类型 self.content = None # 申请内容 self.number = 0 # 申请数量 class Manager(): def __init__(self, name): self.name = name def get_result(self, manager_level, request): if manager_level == "经理": if request.type == "请假" and request.number <=2: print("{}:{} 数量 {} 被批准".format(self.name, request.content, request.number)) else: print("{}:{} 数量 {} 我无权处理".format(self.name, request.content, request.number)) elif manager_level == "总监": if request.type == "请假" and request.number <=5: print("{}:{} 数量 {} 被批准".format(self.name, request.content, request.number)) else: print("{}:{} 数量 {} 我无权处理".format(self.name, request.content, request.number)) elif manager_level == "总经理": if request.type == "请假": print("{}:{} 数量 {} 被批准".format(self.name, request.content, request.number)) elif request.type == "加薪" and request.number <= 500: print("{}:{} 数量 {} 被批准".format(self.name, request.content, request.number)) elif request.type == "加薪" and request.number > 500: print("{}:{} 数量 {} 再说吧".format(self.name, request.content, request.number)) def main(): jingli = Manager("经理") zongjian = Manager("总监") zongjingli = Manager("总经理") request = Request() request.type = "加薪" request.content = "贺贺请求加薪" request.number = 1000 jingli.get_result(jingli.name, request) zongjian.get_result(zongjian.name, request) zongjingli.get_result(zongjingli.name, request) request.type = "请假" request.content = "贺贺请求请假" request.number = 3 jingli.get_result(jingli.name, request) zongjian.get_result(zongjian.name, request) zongjingli.get_result(zongjingli.name, request) main() 经理:贺贺请求加薪 数量 1000 我无权处理 总监:贺贺请求加薪 数量 1000 我无权处理 总经理:贺贺请求加薪 数量 1000 再说吧 经理:贺贺请求请假 数量 3 我无权处理 总监:贺贺请求请假 数量 3 被批准 总经理:贺贺请求请假 数量 3 被批准

点评

Manager类的get_result方法比较长,有太多的分支判断,不是好的设计;Mangeer类有太多的责任,违背了单一职责的原则,增加新的管理者,需要修改这个类,违背了开放封闭原则;

职责链模式

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

职责链模式基本结构

from abc import ABCMeta, abstractmethod class Handler(): __metaclass__ = ABCMeta def __init__(self): self.successor = None # 设置继任者 @abstractmethod def handle_request(self, request): pass class ConcretHandler1(Handler): """ 处理0-10的请求 """ def handle_request(self, request): if request >=0 and request < 10: print("handler1 handle request [ {} ]".format(request)) elif self.successor != None: # 由继任者处理请求 self.successor.handle_request(request) class ConcretHandler2(Handler): """ 处理10-20的请求 """ def handle_request(self, request): if request >=10 and request < 20: print("handler2 handle request [ {} ]".format(request)) elif self.successor != None: # 由继任者处理请求 self.successor.handle_request(request) class ConcretHandler3(Handler): """ 处理20-30的请求 """ def handle_request(self, request): if request >=20 and request < 30: print("handler3 handle request [ {} ]".format(request)) elif self.successor != None: # 由继任者处理请求 self.successor.handle_request(request) def main(): h1 = ConcretHandler1() h2 = ConcretHandler2() h3 = ConcretHandler3() h1.successor = h2 h2.successor = h3 requests = [2, 5, 14, 22, 18, 3, 27, 20] for i in requests: h1.handle_request(i) main() handler1 handle request [ 2 ] handler1 handle request [ 5 ] handler2 handle request [ 14 ] handler3 handle request [ 22 ] handler2 handle request [ 18 ] handler1 handle request [ 3 ] handler3 handle request [ 27 ] handler3 handle request [ 20 ]

点评

当客户提交一个请求时,请求是沿着职责链传递直至有一个ConcretHandler对象负责处理它接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构职责链可以简化对象的相互链接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接收者的引用可以随时增加或修改处理一个请求的结构,增强了给对象指派职责的灵活性一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理最重要的两点 需要实现给每个具体管理者设置它的上司,也就是它的后继者需要在每个具体管理者类处理请求时,做出判断,是可以处理请求,还是必须“推卸责任”,转移到后继者

职责链模式——加薪代码

from abc import ABCMeta, abstractmethod class Manager(): __metaclass__ = ABCMeta def __init__(self, name): self.name = name self.successor = None @abstractmethod def handle_request(self, request): pass class CommonManager(Manager): def handle_request(self, request): if request.type == "请假" and request.number <=2: print("{}:{} 数量 {} 被批准".format(self.name, request.content, request.number)) elif self.successor != None: self.successor.handle_request(request) class Majordomo(Manager): def handle_request(self, request): if request.type == "请假" and request.number <=5: print("{}:{} 数量 {} 被批准".format(self.name, request.content, request.number)) elif self.successor != None: self.successor.handle_request(request) class GeneralManager(Manager): def handle_request(self, request): if request.type == "请假": print("{}:{} 数量 {} 被批准".format(self.name, request.content, request.number)) elif request.type == "加薪" and request.number <= 500: print("{}:{} 数量 {} 被批准".format(self.name, request.content, request.number)) elif request.type == "加薪" and request.number > 500: print("{}:{} 数量 {} 再说吧".format(self.name, request.content, request.number)) def main(): jingli = CommonManager("经理") zongjian = Majordomo("总监") zongjingli = GeneralManager("总经理") jingli.successor = zongjian zongjian.successor = zongjingli request = Request() request.type = "加薪" request.content = "贺贺请求加薪" request.number = 1000 jingli.handle_request(request) request.type = "请假" request.content = "贺贺请求请假" request.number = 3 jingli.handle_request(request) main() 总经理:贺贺请求加薪 数量 1000 再说吧 总监:贺贺请求请假 数量 3 被批准

职责链模式和状态模式

职责链模式,主要处理requet和handler的问题,当handler收到requet时,判断是否自己是否可以处理,处理逻辑在handler中;状态模式,主要处理state和context的问题,当state变化时,改变context的state,继续调用context的处理逻辑,处理逻辑在context中;

转载于:https://www.cnblogs.com/CheeseZH/p/9478386.html


最新回复(0)