Design 责任链模式
基本介绍
责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。
这种模式给予请求的类型,对请求的发送者和接收者进行解耦,属于行为型模式。
在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推(亦可反之,一个处理了给下一个,直到处理完毕或其中一个不再进行处理)。
特点:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止
案例图示
这里有3种等级的日志,info、warning、error。
info日志会记录所有类型的日志、warning日志则只记录warning与info类型的日志,error日志只记录error类型的日志。
整个记录过程是一个链式的顺序,如图所示:
优缺点
优点:
- 降低耦合度,一个请求将被分为接收者和发送者
- 简化了对象,使得对象不需要知道链的结构
- 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任
- 增加新的请求处理类很方便
缺点:
- 不能保证请求一定被接收
- 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用
- 可能不容易观察运行时的特征,有碍于除错
Python实现
用Python实现责任链模式,与描述的责任链不同,但也属于责任链模式,在描述中是从error向info传递,error不记录则交给warning或者info,这里是不一样的,但是效果相同:
import datetime
log_level = {
"info": 10,
"warning": 20,
"error": 30
}
class LogBase(object):
def __init__(self, level_str, level_int):
self.level_str = level_str
self.level_int = level_int
self.prev = None
self.current_level = log_level[self.__class__.__name__.lower()]
def write(self, message):
# 当前等级能写就写入,再判断是否有上级,有就通知
if self.check_level():
print("%s:[%s]:%s -- %s日志写入" % (datetime.datetime.now(), self.level_str, message, self.__class__.__name__))
# 如果有上级对象
if self.prev:
self.call_prev(message)
# 不能写入就返回
def check_level(self):
# 如果日志等级不小于当前等级,就记录
if not self.level_int < self.current_level:
return True
def call_prev(self, message):
self.prev.write(message)
class Error(LogBase):
pass
class Warning(LogBase):
def __init__(self, level_str, level_int):
super(Warning, self).__init__(level_str, level_int)
self.prev = Error(level_str, level_int)
class Info(LogBase):
def __init__(self, level_str, level_int):
super(Info, self).__init__(level_str, level_int)
self.prev = Warning(level_str, level_int)
class Logger(object):
def __init__(self):
self.entrance_log_obj = None
def write(self, level_str, message):
level_str = level_str
level_int = log_level[level_str.lower()]
# 实例化info级别的日志
self.entrance_log_obj = Info(level_str, level_int)
# 写入日志,从info开始写
self.entrance_log_obj.write(message)
if __name__ == '__main__':
logger = Logger()
logger.write("error", "this is error")
print("*" * 10)
logger.write("warning", "this is warning")
print("*" * 10)
logger.write("info", "this is info")
结果如下:
2021-04-13 21:14:58.188867:[error]:this is error -- Info日志写入
2021-04-13 21:14:58.189008:[error]:this is error -- Warning日志写入
2021-04-13 21:14:58.189061:[error]:this is error -- Error日志写入
**********
2021-04-13 21:14:58.189101:[warning]:this is warning -- Info日志写入
2021-04-13 21:14:58.189118:[warning]:this is warning -- Warning日志写入
**********
2021-04-13 21:14:58.189207:[info]:this is info -- Info日志写入
Golang实现
用Golang实现责任链模式:
...