Python的行为设计模式之责任链模式

Posted zy_dream

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python的行为设计模式之责任链模式相关的知识,希望对你有一定的参考价值。

这章来讲行为设计模式,关注做事的过程,也就是算法及对象间的交互。首先来看的是责任链模式。          

“责任链模式”,可将请求的发送方与处理请求的接收方解耦。
解耦这个词厉害了:两个或者两个以上的体系或两种运动形式间通过相互作用而彼此影响以至于联合起来的现象
意思就是,在几个物体身上发生相似的事件,可以像流水线的形式走完。
常规的方式就是一个基类,然后几个子类,用函数参数套函数的形式来完成责任链。

这里我们来展示一下“基于协程的责任链”。
“协程”与生成器一样,也使用 yield 表达式,但行为却不同。关于 yield 的经典使用,我推荐阅读之前这篇 http://blog.csdn.net/zy_dream/article/details/70336290,你会明白 yield 什么叫“挂起”。
而协程,是一开始就停在首个(或仅有的那个)yield 表达式那里,等着值传过去。一般的都是函数执行到 yield 其才发挥自己的作用。而协程就是先在 yield,再执行。
协程就是这样不断的循环下去,从而达到“链”这个效果,当然在使用的时候,也同样是用函数参数为函数的形式来执行。例子:

pipeline = key_handler(mouse_handler(timer_handler()))
while True:
    event = Event.next()
    if event.kind == Event.TERMINATE:
        break
    pipeline.send(event)
通过 send 来推送值。然后把值,这里的 event 传送给 yield ,此时 yield 就相当于接受容器来存放 event,对 event 进行判断:是你的东西还是送给其他人:

@coroutine
def key_handler(successor=None):
    while True:
        event = (yield)
        if event.kind == Event.KEYPRESS:
            print ("Press: ".format(event))
        elif successor is not None:
            successor.send(event)


@coroutine
def mouse_handler(successor=None):
    while True:
        event = (yield)
        if event.kind == Event.MOUSE:
            print ("Click: ".format(event))
        elif successor is not None:
            successor.send(event)


@coroutine
def timer_handler(successor=None):
    while True:
        event = (yield)
        if event.kind == Event.TIMER:
            print ("Time: ".format(event))
        elif successor is not None:
            successor.send(event)
至于修饰器:

def coroutine(function):
    @function.wraps(function)
    def wrapper(*args, **kwargs):
        generator = function(*args, **kwargs)
        next(generator)
        return generator
    return wrapper
懂了,有了 coroutine 中的 next() ,才能对 key_handler(mouse_handler(timer_handler())) 进行递归的判断。因为书上说是把生成器对象放入 generator 里面,而生成器对象不就是 event=(yield) 吗。


From in book:
尽管协程的机制与生成器相同,但用法却差别很大,使用一般的生成器时,我们是每次提取一个值出来,例如 for x in range(10): yield x。
而使用协程时,则要每次使用 send() 推送一个值进去。


以上是关于Python的行为设计模式之责任链模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之责任链模式(行为型)

设计模式之责任链模式(行为型)

18行为型模式之责任链模式

行为型设计模式之责任链模式

JAVA设计模式之责任链模式

行为型模式:责任链模式