📜  责任链Python设计模式

📅  最后修改于: 2022-05-13 01:55:40.255000             🧑  作者: Mango

责任链Python设计模式

责任链方法是行为设计模式,它是if ... elif ... elif ... else的面向对象版本,使我们能够在运行时动态重新排列条件动作块。它允许我们沿着处理程序链传递请求。处理很简单,每当任何处理程序收到请求时,它都有两种选择来处理它或将其传递给链中的下一个处理程序。
该模式旨在通过允许请求通过链接的接收器直到它被处理来将请求的发送者与其接收者分离。

责任链法

不使用责任链方法的问题

想象一下,您正在构建一个简单的网站,该网站接受输入字符串并讲述字符串字符串?是字符串大写吗?字符串是小写的吗?以及许多其他属性。完成计划后,您决定对输入字符串的这些检查应按顺序执行。因此,对于开发人员来说,问题出现了,他/她必须实现这样一个应用程序,该应用程序可以在运行时决定下一步应该执行哪个操作。

使用责任链方法的解决方案

责任链方法为上述问题提供了解决方案。它创建了一个单独的抽象处理程序,用于处理应该动态执行的顺序操作。例如,我们创建了四个处理程序,分别命名为FirstConcreteHandler、SecondConcreteHandler、ThirdConcreteHandlerDefaulthandler ,并从用户类中依次调用它们。

Python3
class AbstractHandler(object):
 
    """Parent class of all concrete handlers"""
 
    def __init__(self, nxt):
 
        """change or increase the local variable using nxt"""
 
        self._nxt = nxt
 
    def handle(self, request):
 
        """It calls the processRequest through given request"""
 
        handled = self.processRequest(request)
 
        """case when it is not handled"""
 
        if not handled:
            self._nxt.handle(request)
 
    def processRequest(self, request):
 
        """throws a NotImplementedError"""
 
        raise NotImplementedError('First implement it !')
 
 
class FirstConcreteHandler(AbstractHandler):
 
    """Concrete Handler # 1: Child class of AbstractHandler"""
 
    def processRequest(self, request):
 
        '''return True if request is handled '''
 
        if 'a' < request <= 'e':
            print("This is {} handling request '{}'".format(self.__class__.__name__, request))
            return True
 
 
class SecondConcreteHandler(AbstractHandler):
 
    """Concrete Handler # 2: Child class of AbstractHandler"""
 
    def processRequest(self, request):
 
        '''return True if the request is handled'''
 
        if 'e' < request <= 'l':
            print("This is {} handling request '{}'".format(self.__class__.__name__, request))
            return True
 
class ThirdConcreteHandler(AbstractHandler):
 
    """Concrete Handler # 3: Child class of AbstractHandler"""
 
    def processRequest(self, request):
 
        '''return True if the request is handled'''
 
        if 'l' < request <= 'z':
            print("This is {} handling request '{}'".format(self.__class__.__name__, request))
            return True
 
class DefaultHandler(AbstractHandler):
 
    """Default Handler: child class from AbstractHandler"""
 
    def processRequest(self, request):
 
        """Gives the message that th request is not handled and returns true"""
 
        print("This is {} telling you that request '{}' has no handler right now.".format(self.__class__.__name__,
                                                                                          request))
        return True
 
 
class User:
 
    """User Class"""
 
    def __init__(self):
 
        """Provides the sequence of handles for the users"""
 
        initial = None
 
        self.handler = FirstConcreteHandler(SecondConcreteHandler(ThirdConcreteHandler(DefaultHandler(initial))))
 
    def agent(self, user_request):
 
        """Iterates over each request and sends them to specific handles"""
 
        for request in user_request:
            self.handler.handle(request)
 
"""main method"""
 
if __name__ == "__main__":
 
    """Create a client object"""
    user = User()
 
    """Create requests to be processed"""
 
    string = "GeeksforGeeks"
    requests = list(string)
 
    """Send the requests one by one, to handlers as per the sequence of handlers defined in the Client class"""
    user.agent(requests)


输出

This is DefaultHandler telling you that request 'G' has no handler right now.
This is FirstConcreteHandler handling request 'e'
This is FirstConcreteHandler handling request 'e'
This is SecondConcreteHandler handling request 'k'
This is ThirdConcreteHandler handling request 's'
This is SecondConcreteHandler handling request 'f'
This is ThirdConcreteHandler handling request 'o'
This is ThirdConcreteHandler handling request 'r'
This is DefaultHandler telling you that request 'G' has no handler right now.
This is FirstConcreteHandler handling request 'e'
This is FirstConcreteHandler handling request 'e'
This is SecondConcreteHandler handling request 'k'
This is ThirdConcreteHandler handling request 's'

类图

责任链方法的类图

责任链_class_diagram

好处

  • 单一职责原则:这里很容易将调用操作的类与执行操作的类解耦。
  • 开放/封闭原则:我们可以在不破坏现有客户端代码的情况下引入新的代码类。
  • 增加灵活性:在赋予对象职责的同时,增加了代码的灵活性。

缺点

  • 不保证请求:此方法不保证是否会收到对象。
  • 发现特征:由于调试,很难观察操作的特征。
  • 折旧的系统性能:由于连续的循环调用,它可能会影响系统的性能

适用性

  • 按顺序处理多个处理程序:当需要按特定顺序处理多个处理程序时,责任链方法非常有用,因为可以按任何顺序进行链接
  • 解耦请求:这个方法一般用于解耦请求的发送者和接收者的时候。
  • 未指定的处理程序:当您不想在代码中指定处理程序时,始终首选使用责任链

进一步阅读Java中的责任链