Python设计模式——责任链模式

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

使用常规方法实现

#!/usr/bin/env python
# encoding:utf-8

class NullHandler(object):
    def __init__(self, successor=None):
        self.__successor = successor

    def 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", event
        else:
            super(ConcreteHandler1, self).handle(event)


class ConcreteHandler2(NullHandler):
    def handle(self, event):
        if event > 10 and event <= 20:
            print "in handler2", event
        else:
            super(ConcreteHandler2, self).handle(event)


class ConcreteHandler3(NullHandler):
    def handle(self, event):
        if event > 20 and event <= 30:
            print "in handler3", event
        else:
            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 functools

def coroutine(function):
    @functools.wraps(function)
    def wrapper(*args, **kwargs):
        generator = function(*args, **kwargs)
        next(generator)#调用一次生成器,令生成器对象前进到首个yield表达式。
        return generator
    return 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()
    原文作者:BingLau
    原文地址: https://blog.csdn.net/qingyunianer/article/details/44244355
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞