Design 责任链模式

基本介绍

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

这种模式给予请求的类型,对请求的发送者和接收者进行解耦,属于行为型模式。

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

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

案例图示

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

info日志会记录所有类型的日志、warning日志则只记录warning与info类型的日志,error日志只记录error类型的日志。

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

image-20210413185844231

优缺点

优点:

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

缺点:

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

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实现责任链模式:

...
posted @ 2021-04-13 21:20  云崖君  阅读(55)  评论(0编辑  收藏  举报