每天一个设计模式之责任链模式

栏目: 后端 · 发布时间: 6年前

内容简介:作者按:《每天一个设计模式》旨在初步领会设计模式的精髓,目前采用责任链模式:多个对象均有机会处理请求,从而其核心就是:

作者按:《每天一个设计模式》旨在初步领会 设计模式 的精髓,目前采用 javascriptpython 两种语言实现。诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式 :)

0. 项目地址

1. 什么是“责任链模式”?

责任链模式:多个对象均有机会处理请求,从而 解除 发送者和接受者之间的耦合关系。这些对象连接成为 链式结构 ,每个节点转发请求,直到有对象处理请求为止。

其核心就是: 请求者不必知道是谁哪个节点对象处理的请求 。如果当前不符合终止条件,那么把请求转发给下一个节点处理。

而当需求具有“传递”的性质时(代码中其中一种体现就是:多个 if、else if、else if、else 嵌套),就可以考虑将每个分支拆分成一个节点对象,拼接成为责任链。

2. 优点与代价

  • 优点
    • 可以根据需求变动,任意向责任链中添加 / 删除节点对象
    • 没有固定的“开始节点”,可以从任意节点开始
  • 代价: 责任链最大的代价就是每个节点带来的多余消耗 。当责任链过长,很多节点只有传递的作用,而不是真正地处理逻辑。

3. 代码实现

为了方便演示,模拟常见的“日志打印”场景。模拟了 3 种级别的日志输出:

LogHandler
WarnHandler
ErrorHandler

首先我们会构造“责任链”: LogHandler -> WarnHandler -> ErrorHandlerLogHandler 作为链的开始节点。

如果是普通日志,那么就由 LogHandler 处理,停止传播;如果是 Warn 级别的日志,那么 LogHandler 就会自动向下传递, WarnHandler 接收到并且处理,停止传播;Error 级别日志同理。

3.1 ES6 实现

class Handler {
  constructor() {
    this.next = null;
  }

  setNext(handler) {
    this.next = handler;
  }
}

class LogHandler extends Handler {
  constructor(...props) {
    super(...props);
    this.name = "log";
  }

  handle(level, msg) {
    if (level === this.name) {
      console.log(`LOG: ${msg}`);
      return;
    }
    this.next && this.next.handle(...arguments);
  }
}

class WarnHandler extends Handler {
  constructor(...props) {
    super(...props);
    this.name = "warn";
  }

  handle(level, msg) {
    if (level === this.name) {
      console.log(`WARN: ${msg}`);
      return;
    }
    this.next && this.next.handle(...arguments);
  }
}

class ErrorHandler extends Handler {
  constructor(...props) {
    super(...props);
    this.name = "error";
  }

  handle(level, msg) {
    if (level === this.name) {
      console.log(`ERROR: ${msg}`);
      return;
    }
    this.next && this.next.handle(...arguments);
  }
}

/******************以下是测试代码******************/

let logHandler = new LogHandler();
let warnHandler = new WarnHandler();
let errorHandler = new ErrorHandler();

// 设置下一个处理的节点
logHandler.setNext(warnHandler);
warnHandler.setNext(errorHandler);

logHandler.handle("error", "Some error occur");

3.2 Python 3 实现

class Handler():
    def __init__(self):
        self.next = None

    def set_next(self, handler):
        self.next = handler


class LogHandler(Handler):
    def __init__(self):
        super().__init__()
        self.__name = "log"

    def handle(self, level, msg):
        if level == self.__name:
            print('LOG: ', msg)
            return

        if self.next != None:
            self.next.handle(level, msg)


class WarnHandler(Handler):
    def __init__(self):
        super().__init__()
        self.__name = "warn"

    def handle(self, level, msg):
        if level == self.__name:
            print('WARN: ', msg)
            return

        if self.next != None:
            self.next.handle(level, msg)


class ErrorHandler(Handler):
    def __init__(self):
        super().__init__()
        self.__name = "error"

    def handle(self, level, msg):
        if level == self.__name:
            print('ERROR: ', msg)
            return

        if self.next != None:
            self.next.handle(level, msg)


# 以下是测试代码
log_handler = LogHandler()
warn_handler = WarnHandler()
error_handler = ErrorHandler()

# 设置下一个处理的节点
log_handler.set_next(warn_handler)
warn_handler.set_next(error_handler)

log_handler.handle("error", "Some error occur")

4. 参考


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

从零到百亿

从零到百亿

〔美〕卡罗·白朗、Karel Baloun、卡罗·白朗 / 译言网 / 中国书籍出版社 / 2007 / 15.00元

Facebook是一个发源于哈佛大学、为全美大学生服务的社交网站。按照流量,这个网站在世界范围排名第8名;按照价值,业界对Facebook公司的估值超过10亿美元。Facebook创建于2004年2月,这样的高速增长成为当今互联网发展的一个奇迹。 《Inside Facebook》这本书是原作者卡罗·白朗(Karel Baloun)作为Facebook的第一位高级软件开发人员之一,在Face......一起来看看 《从零到百亿》 这本书的介绍吧!

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具