Python 设计模式:责任链模式的优点与缺点

2023-04-03 00:00:00 模式 优点 缺点

责任链模式(Chain of Responsibility)是一种行为设计模式,它允许多个对象按照顺序处理请求,直到其中一个对象能够处理该请求为止。

优点:

  • 解耦:责任链模式将请求的发送者和接收者解耦,使得请求的发送者不需要知道请求最终由哪个接收者处理。
  • 灵活性:责任链模式可以动态地组合处理者对象,可以在运行时动态地增加或删除处理者,从而使得系统更加灵活。
  • 可扩展性:可以很容易地增加或修改处理一个请求的方式。
  • 降低耦合度:将请求和处理分离,避免了请求发送者和接收者之间的耦合关系。
  • 符合开闭原则:新增一个处理者只需要修改链中的顺序或者增加一个处理者,不需要修改已有的代码。

缺点:

  • 请求没有明确的接收者,可能会出现请求无法被处理的情况。
  • 对于长链的处理,可能会影响系统性能。
  • 需要对责任链的执行顺序进行管理。

代码演示:

下面是一个以字符串中是否包含"pidancode.com"作为判断条件的责任链模式的示例:

class Handler:
    def __init__(self, successor=None):
        self._successor = successor

    def handle(self, request):
        handled = self._handle(request)

        if not handled:
            self._successor.handle(request)

    def _handle(self, request):
        raise NotImplementedError('Must provide implementation in subclass.')


class PidancodeHandler(Handler):
    def _handle(self, request):
        if 'pidancode.com' in request:
            print('PidancodeHandler: Handling the request.')
            return True
        else:
            return False


class PidengHandler(Handler):
    def _handle(self, request):
        if '皮蛋编程' in request:
            print('PidengHandler: Handling the request.')
            return True
        else:
            return False


class DefaultHandler(Handler):
    def _handle(self, request):
        print('DefaultHandler: Unable to find the appropriate handler.')
        return True


if __name__ == '__main__':
    pidancode_handler = PidancodeHandler()
    pideng_handler = PidengHandler(pidancode_handler)
    default_handler = DefaultHandler(pideng_handler)

    requests = ['www.pideng.com', 'www.pidancode.com', 'www.baidu.com']

    for request in requests:
        default_handler.handle(request)

在上面的代码中,我们创建了三个处理者类:PidancodeHandler、PidengHandler和DefaultHandler。它们都继承自Handler类,并且覆盖了_handler()方法,用于处理请求。

我们首先创建了PidancodeHandler实例,然后将它作为参数创建PidengHandler实例,最后将PidengHandler实例作为参数创建DefaultHandler实例。

在处理请求时,我们首先将请求发送给DefaultHandler实例,如果DefaultHandler实例不能处理该请求,它就将请求转发给PidengHandler实例,如果PidengHandler实例也不能处理该请求,它就将请求转发给PidancodeHandler实例。如果PidancodeHandler实例能够处理该请求,它就处理该请求,否则,它就返回False,告诉上一个处理者继续处理该请求。

在上面的代码中,我们创建了三个处理者类:PidancodeHandler、PidengHandler和DefaultHandler。它们都继承自Handler类,并且覆盖了_handle()方法,用于处理请求。

我们首先创建了PidancodeHandler实例,然后将它作为参数创建PidengHandler实例,最后将PidengHandler实例作为参数创建DefaultHandler实例。

在处理请求时,我们首先将请求发送给DefaultHandler实例,如果DefaultHandler实例不能处理该请求,它就将请求转发给PidengHandler实例,如果PidengHandler实例也不能处理该请求,它就将请求转发给PidancodeHandler实例。如果PidancodeHandler实例能够处理该请求,它就处理该请求,否则,它就返回False,告诉上一个处理者继续处理该请求。

下面是上述代码的输出结果:

DefaultHandler: Unable to find the appropriate handler.
PidengHandler: Handling the request.
PidancodeHandler: Handling the request.

可以看到,在处理请求时,首先由DefaultHandler实例尝试处理请求,但它无法处理该请求,所以将请求转发给PidengHandler实例,PidengHandler实例也无法处理该请求,所以将请求转发给PidancodeHandler实例,PidancodeHandler实例最终处理了该请求。

相关文章