责任链模式


责任链模式(Chain of Responsibility)

简介

责任链模式是一种行为设计模式,它允许您将请求沿着处理链传递,直到有一个对象能够处理它为止。举个例子,当您点击 GUI 应用程序中的按钮时,单击事件将先传递给最顶层的部件。如果部件不能处理它,它将被传递给下一个部件,以此类推,直到有一个能够处理事件为止。

需求

有一个旅游行程申请审批的场景。假设公司有以下三个管理层级:经理、CEO和董事会主席。如果在某个层级进行了拒绝,则整个申请过程被拒绝,否则它将被批准。该场景可以使用责任链模式实现。

实现

在具体实现中,我们需要定义一个抽象 Handler 类,该类将定义处理请求的接口。Handler 类必须具有一个记录下一个处理程序的引用的字段,并定义一个处理请求的方法。

class Handler:
    def __init__(self):
        self._next_handler = None
 
    def set_next(self, handler):
        self._next_handler = handler
        return handler
 
    def handle(self, request):
        if self._next_handler:
            return self._next_handler.handle(request)
        return None

我们还需要根据要求实现具体的处理过程,例如,管理层级的责任链定义如下:

class Manager(Handler):
    def handle(self, request):
        if request.level <= 1:
            return f"The request {request.content} has been approved by Manager."
        else:
            return super().handle(request)
 
 
class Ceo(Handler):
    def handle(self, request):
        if request.level <= 2:
            return f"The request {request.content} has been approved by Ceo."
        else:
            return super().handle(request)
 
 
class Chairman(Handler):
    def handle(self, request):
        if request.level <= 3:
            return f"The request {request.content} has been approved by Chairman."
        else:
            return f"The request {request.content} has been refused by Chairman."

在上述代码中,每个具体的处理程序都负责处理请求。如果请求级别高于层级,则将请求传递给链中下一个处理程序。否则,它将批准请求。

使用

我们可以使用下面的代码测试整个责任链的工作过程:

if __name__ == '__main__':
    # 初始化责任链
    manager = Manager()
    ceo = Ceo()
    chairman = Chairman()
    manager.set_next(ceo).set_next(chairman)
 
    # 创建请求并将其发送给责任链
    request1 = Request('Conduct business trip to USA', 1)
    request2 = Request('Conduct business trip to Japan', 2)
    request3 = Request('Conduct business trip to India', 3)
    print(manager.handle(request1))
    print(manager.handle(request2))
    print(manager.handle(request3))

输出结果如下:

The request Conduct business trip to USA has been approved by Manager.
The request Conduct business trip to Japan has been approved by Ceo.
The request Conduct business trip to India has been refused by Chairman.

总结

在责任链模式中,请求沿着一个链传递,直到找到一个能够处理请求的对象为止。该模式可以灵活地添加或移除请求处理程序,并让客户端从详细级别中解耦。

责任链模式包含以下角色:

  • Handler:负责定义处理请求的接口,并维护下一个处理程序的引用。
  • ConcreteHandler:具体的处理程序,可以处理请求或将其传递给链中的下一个处理程序。
  • Client:创建具体处理程序并将请求发送到链中的第一个处理程序。

责任链模式的优点:

  • 简化了对象之间的链接。通过使用连接接口,客户无需知道哪个类处理其请求。它只需建立与抽象处理程序之间的关系即可。
  • 可以灵活地调整链。您可以通过添加或删除链接器来轻松更改链。
  • 提高了系统的可扩展性。您可以为系统构建任意数量的链接器,从而扩展其功能。

责任链模式的缺点:

  • 一个坏处理程序可能会使链无法正常工作。如果某个处理程序不正确地处理了请求,则可能无法将请求正确发送到下一个处理程序。

责任链模式常用于以下场景:

  • 我们需要从不同组件中选择一个件,而不想知道处理请求的具体组件。
  • 我们需要顺序处理请求。例如,从用户界面处理事件或从服务器读取数据。
  • 请求的结构可能随时间而变化,并会导致请求发送者和接收者出现起伏。使用此模式,可以使请求的处理者动态更改。