责任链模式

71 阅读4分钟

1. 简介

责任链模式是一种行为设计模式,它允许多个对象共同处理请求,而无需明确指定接收者。在责任链模式中,将请求发送者和接收者解耦,并允许多个对象依次处理请求,直到其中一个对象能够处理为止。

2. 模式结构

classDiagram
    class Client {
        +client()
    }
    
    class Request {
        -argment: Any
    }
    
    class Handler {
        <<interface>>
        +handle(req: Request)
    }
    
    class ConcreteHandler {
        -nextHandler: Handler
        +canHandle(req: Request): bool
        +handle(req: Request)
    }
    
    Handler <|.. ConcreteHandler
    Handler ..> Request
    Client ..> Request
    Client ..> ConcreteHandler

主要参与角色:

  1. 抽象处理者(Handler) : 定义了一个处理请求的接口,通常包含一个处理请求的方法。

  2. 具体处理者(Concrete Handler) : 具体处理者是抽象处理者的具体实现,负责处理请求。它可以决定是否处理请求,或者将请求传递给下一个处理者。

  3. 请求(Request): 请求对象,可选,主要是为Handler封装请求参数。

  4. 客户端(Client) : 客户端创建请求,并将请求发送给第一个处理者。

3. 优缺点以及使用场景

优点:

  1. 解耦请求发送者和接收者:责任链模式可以解耦请求发送者和接收者,使得它们之间不需要直接交互。
  2. 灵活性和可扩展性:责任链模式允许动态添加或修改处理者,从而实现灵活的责任链结构,满足不同场景的需求。
  3. 降低耦合度:责任链模式将请求的发送者和接收者解耦,降低了系统的耦合度,增强了系统的灵活性和可维护性。

缺点:

  1. 请求可能无法被处理:责任链中的请求可能无法被任何处理者处理,导致请求未被处理的情况发生。
  2. 性能影响:责任链模式的处理者链可能较长,可能会影响请求的处理性能。

使用场景:

  1. 请求需要被多个对象处理:当一个请求需要被多个对象依次处理时,可以使用责任链模式。
  2. 请求的接收者需要动态确定:当请求的接收者不能提前确定,或者需要动态确定时,可以使用责任链模式。
  3. 避免请求发送者和接收者之间的紧耦合:当需要避免请求发送者和接收者之间的直接耦合时,可以使用责任链模式。

4. 练习:【设计模式专题之责任链模式】21-请假审批

""" 
【设计模式专题之责任链模式】21-请假审批
时间限制:1.000S  空间限制:256MB
题目描述
小明所在的公司请假需要在OA系统上发布申请,整个请求流程包括多个处理者,每个处理者负责处理不同范围的请假天数,如果一个处理者不能处理请求,就会将请求传递给下一个处理者,请你实现责任链模式,可以根据请求天数找到对应的处理者。

审批责任链由主管(Supervisor), 经理(Manager)和董事(Director)组成,他们分别能够处理3天、7天和10天的请假天数。如果超过10天,则进行否决。

输入描述
第一行是一个整数N(1 <= N <= 100), 表示请求申请的数量。

接下来的N行,每行包括一个请求申请的信息,格式为"姓名 请假天数"

输出描述
对于每个请假请求,输出一行,表示该请求是否被批准。如果被批准/否决,输出被哪一个职级的人批准/否决。
输入示例
4
Alice 2
Bob 5
Tom 10
Jerry 12
输出示例
Alice Approved by Supervisor.
Bob Approved by Manager.
Tom Approved by Director.
Jerry Denied by Director.
"""


from abc import ABC, abstractmethod


class LeaveRequest:
    def __init__(self, name: str, days: int):
        self.name: str = name
        self.days: int = days
        
        
class Approver(ABC):
    @abstractmethod
    def approve(self, req: LeaveRequest):
        raise NotImplemented
        
        
class ConcreteApprover(Approver):
    def __init__(self, title: str):
        self._nextApprover = None
        # self.days = 0  # 让子类来初始化
        self.title = title
        
    @property
    def nextApprover(self) -> Approver:
        return self._nextApprover
        
    @nextApprover.setter
    def nextApprover(self, approver: Approver):
        self._nextApprover = approver
        
    def approve(self, req: LeaveRequest) -> bool:
        if req.days <= self.days:
            print(f"{req.name} Approved by {self.title}.")
        elif self.nextApprover is not None:
            self.nextApprover.approve(req)
        else:
            print(f"{req.name} Denied by {self.title}.")
        

class Director(ConcreteApprover):
    def __init__(self, title: str):
        super().__init__(title)
        self.days = 10
        

class Manager(ConcreteApprover):
    def __init__(self, title: str):
        super().__init__(title)
        self.days = 7
        
        
class Supervisor(ConcreteApprover):
    def __init__(self, title: str):
        super().__init__(title)
        self.days = 3
        
        
def client():
    director = Director(title="Director")
    manager = Manager(title="Manager")
    supervisor = Supervisor(title="Supervisor")
    supervisor.nextApprover = manager
    manager.nextApprover = director
    
    n = int(input())
    for _ in range(n):
        name, days = input().split()
        days = int(days)
        supervisor.approve(LeaveRequest(name, days))
        

if __name__ == "__main__":
    client()

5. 参考文章