责任链模式(Chain of Responsibility Pattern)可将请求的发送方与处理请求的接收方解耦。这样的话,某函数就不用直接调用别的函数了,而是可以把请求发送给一个由诸多接收者所组成的链条。链条中的首个接收者可以处理请求并停止责任链(也就是不再继续往下传递),也可以把请求发给下一个接收者。而第二个接收者也有这两种选择,此过程可一直延续至最后一个接收者,该接收者可将请求丢弃,也可抛出异常。

使用常规方法实现

#!/usr/bin/env python
# encoding:utf-8class NullHandler(object):def __init__(self, successor=None):self.__successor = successordef handle(self, event):if self.__successor is not None:self.__successor.handle(event)class ConcreteHandler1(NullHandler):def handle(self, event):if event > 0 and event <= 10:print "in handler1", eventelse:super(ConcreteHandler1, self).handle(event)class ConcreteHandler2(NullHandler):def handle(self, event):if event > 10 and event <= 20:print "in handler2", eventelse:super(ConcreteHandler2, self).handle(event)class ConcreteHandler3(NullHandler):def handle(self, event):if event > 20 and event <= 30:print "in handler3", eventelse:super(ConcreteHandler3, self).handle(event)def main():handler = ConcreteHandler3(ConcreteHandler2(ConcreteHandler1(NullHandler())))events = [2, 5, 14, 22, 18, 3, 35, 27, 20]for event in events:handler.handle(event)

所示代码在NullHandler设置一个successor属性,使用它来执行handle,而其他则继承NullHandler,这样不符合自身条件将它抛给NullHandler,让它来执行successorhandle。我们可以从上面赋值中看出successor的顺序,一开始最里面successorNone,后面是ConcreteHandler1类型…依次类推,实现责任链。

使用协程实现责任链

关于协程

协程(coroutine)与生成器一样,也使用yield表达式,但行为不同。协程执行的是无限循环,而且一开始就会停在首个(或仅有的那个)yield表达式那里,等值有值传给它。协程会把收到的值当成yield表达式的值,然后继续执行它所需的操作,等处理完之后,又会再度循环,并在下一个yield表达式那里等着接收下个值。这样的话,我们就能反复调用协程中的send()throw()方法向其push值。
在Python中,凡是带有yield语句的函数或方法都能充当生成器。而利用@coroutine装饰器及无限循环则可将生成器变为协程。

import functoolsdef coroutine(function):@functools.wraps(function)def wrapper(*args, **kwargs):generator = function(*args, **kwargs)next(generator)#调用一次生成器,令生成器对象前进到首个yield表达式。return generatorreturn wrapper
#!/usr/bin/env python
# encoding:utf-8@coroutine
def mouse_handler(successor=None):while True:event = (yield)if 0 < event <= 10:print("mouse-num:   {}".format(event))elif successor is not None:successor.send(event)@coroutine
def key_handler(successor=None):while True:event = (yield)if 10 < event <= 20:print("key-num:   {}".format(event))elif successor is not None:successor.send(event)@coroutine
def timer_handler(successor=None):while True:event = (yield)if 20 < event <= 30:print("timer-num: {}".format(event))elif successor is not None:successor.send(event)def main():pipeline = key_handler(mouse_handler(timer_handler()))events = [2, 5, 14, 22, 18, 3, 35, 27, 20]for event in events:pipeline.send(event)if __name__ == "__main__":main()

Python设计模式——责任链模式相关推荐

  1. Python设计模式-职责链模式

    Python设计模式-职责链模式 代码基于3.5.2,代码如下; #coding:utf-8 #职责链模式class Handler():def __init__(self):self.success ...

  2. Java设计模式-责任链模式

    Java设计模式-责任链模式,我想这是值得你了解一下下的啦. 会了就当复习丫,不会来一起来看看吧. 很喜欢一句话:"八小时内谋生活,八小时外谋发展". 如果你也喜欢,让我们一起坚持 ...

  3. 设计模式--责任链模式--Java实现

    设计模式–责任链模式–Java实现 责任链模式–链式数据结构–内存消耗–Java的awt事件一开始用责任链模式后来改为观察者模式–为什么呢?–现在的应用–dom事件–异常处理机制-过滤器链–等等 学习 ...

  4. 理解各种设计模式原则及区别丨浅谈Nginx中核心设计模式-责任链模式丨C++后端开发丨Linux服务器开发丨web服务器

    理解各种设计模式原则及区别丨浅谈Nginx中核心设计模式-责任链模式 1. 开闭.单一职责.里氏替换.接口隔离等设计原则 2. 随处可见的模板方法 3. nginx中核心设计模式 责任链模式 4. 责 ...

  5. java责任链模式审批请假_Java设计模式-责任链模式

    Java设计模式-责任链模式 Java版本:jdk1.8 IDE:IDEA 一 前言 本文介绍责任链模式以及Java下的实现. 二 概念 1.什么是责任链模式 责任链模式(Chain of Respo ...

  6. 一起学设计模式 - 责任链模式

    责任链模式(ChainOfResponsibilityPattern)属于 行为型模式的一种,将请求沿着一条链传递,直到该链上的某个对象处理它为止. 概述 定义如下:一个请求有多个对象来处理,这些对象 ...

  7. 大话设计模式—责任链模式

    顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这种类型的设计模式属于行为 ...

  8. 设计模式 责任链模式

    责任链模式 顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这种类型的设计 ...

  9. 设计模式--责任链模式

    2019独角兽企业重金招聘Python工程师标准>>> 责任链模式(chain of responsibility): 有多个对象,每个对象持有对下一个对象的引用,这样就会形成一条链 ...

  10. php设计模式-责任链模式

    最近重构代码发现责任链模式非常实用,所以简单总结了一下.总体来说,责任链模式更像是一种简化多种场景下调用处理的一种设计模式,特别适合if-else分支判断很多的场景.比如是根据不同会员等级给予不同的优 ...

最新文章

  1. big endian little endian
  2. android模拟手指滑动,Android Accessibility 模拟界面滑动
  3. 这 30 个常用的 Maven 命令你必须熟悉!
  4. 震撼世界的基建狂魔,中国制造的超级工程到底有多牛?
  5. 木马爱修改的常见注册表项及其功能
  6. pytorch源码解析2——数据处理torch.utils.data
  7. Windows 10开机可以跳过锁屏界面的操作方法
  8. LeetCode 121买卖股票的时机
  9. mysql基础之数据库变量(参数)管理
  10. 如何不用密钥破解tableau
  11. 【NLP 自然语言处理】自然语言处理技术难点和挑战
  12. 阿里云无影云桌面怎么使用?用户名密码连接登录新手教程
  13. 什么是客户旅程分析(customer journey mapping)
  14. 金融分析与风险管理——投资组合收益率、波动率计算
  15. 人脸聚类Learning to Cluster Faces(翻译)
  16. 智能水杯设计方案_智能水杯-设计报告终稿.doc
  17. 单片机定时器(65536-x)/256
  18. FreeSwitch连接讯时语音网关配置和全部使用场景
  19. 女 大三,抱金砖~呵~
  20. latexstudio编译报错问题:无法启动buildview:Xelatex:xelatex.exe -synctex=1 -interacion=nonstopmode

热门文章

  1. 小用lambda表达式,查询数组里大于80的个数
  2. GC.Collect
  3. android view分析工具栏,如何在Android工具栏中使用SearchView
  4. linux .deb后缀文件,tar.gz和bin,以及rpm,deb等linux后缀的文件的区别
  5. Python imageio方法示例
  6. Qt lambda 简化你的代码 connect 写法示例 省略槽函数定义
  7. 一个详细介绍CPU Memory Kernel的博客
  8. 如何配置mysql_怎样配置MySQL
  9. python连接sql server报20002错误_python - 如何修复pymssql中的“20002,严重性9:Adaptive Server连接失败”错误 - 堆栈内存溢出...
  10. GDI GDI+ 的区别