跳到主要内容

14、Python - 责任链模式

基本介绍

责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。

在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推(亦可反之,一个处理了给下一个,直到处理完毕或其中一个不再进行处理)。

特点:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止

该模式属于行为型模式。

案例图示

这里有3种等级的日志,info、warning、error。

它们的优先级是:info < warning < error

info日志只处理info级别的,如果碰见warning或者error级别日志则向上传递,如果碰见info级别的则直接处理并返回,不再向上传递。

整个记录过程是一个链式的顺序,如图所示:

 

优缺点

优点:

  • 降低耦合度,一个请求将被分为接收者和发送者
  • 简化了对象,使得对象不需要知道链的结构
  • 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任
  • 增加新的请求处理类很方便

缺点:

  • 不能保证请求一定被接收
  • 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用
  • 可能不容易观察运行时的特征,有碍于除错

代码实现

用Python实现责任链模式:

import datetime
class LevelBase:
    def write(self, logName, message):
        print("%s:[%s]:[%s] -- %s" % (logName, datetime.datetime.now(),
              self.__class__.__name__.upper(), message))
class Error(LevelBase):
    pass
class Warning(LevelBase):
    pass
class Info(LevelBase):
    pass
class Logger:
    建立等级关系
    logLevel = (Info(), Warning(), Error())

    def __init__(self, logName) -> None:
        self.logName = logName

    def write(self, level, message):
        for ins in __class__.logLevel:
            if level.upper() == ins.__class__.__name__.upper():
                ins.write(self.logName, message)
                break
        else:
            raise ValueError("don't have level %s" % level)
if __name__ == "__main__":
    log = Logger("Yunya")
    log.write("error", "this is error message")
    log.write("info", "this is info message")

# Yunya:[2021-06-24 19:59:52.958078]:[ERROR] -- this is error message
# Yunya:[2021-06-24 19:59:52.958136]:[INFO] -- this is info message