基本介绍
责任链模式(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