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
主要参与角色:
-
抽象处理者(Handler) : 定义了一个处理请求的接口,通常包含一个处理请求的方法。
-
具体处理者(Concrete Handler) : 具体处理者是抽象处理者的具体实现,负责处理请求。它可以决定是否处理请求,或者将请求传递给下一个处理者。
-
请求(Request): 请求对象,可选,主要是为Handler封装请求参数。
-
客户端(Client) : 客户端创建请求,并将请求发送给第一个处理者。
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()