在python中使用协同程序实现责任链模式
问题描述:
我正在探索python中的不同概念,并且偶然发现了一个可用于责任设计模式链的协程的例子。我写了下面的代码:在python中使用协同程序实现责任链模式
from functools import wraps
def coroutine(function):
@wraps(function)
def wrapper(*args, **kwargs):
generator = function(*args, **kwargs)
next(generator)
return generator
return wrapper
@coroutine
def PlatinumCustomer(successor=None):
cust = (yield)
if cust.custtype == 'platinum':
print "Platinum Customer"
elif successor is not None:
successor.send(cust)
@coroutine
def GoldCustomer(successor=None):
cust = (yield)
if cust.custtype == 'gold':
print "Gold Customer"
elif successor is not None:
successor.send(cust)
@coroutine
def SilverCustomer(successor=None):
cust = (yield)
if cust.custtype == 'silver':
print "Silver Customer"
elif successor is not None:
successor.send(cust)
@coroutine
def DiamondCustomer(successor=None):
cust = (yield)
if cust.custtype == 'diamond':
print "Diamond Customer"
elif successor is not None:
successor.send(cust)
class Customer:
pipeline = PlatinumCustomer(GoldCustomer(SilverCustomer(DiamondCustomer())))
def __init__(self,custtype):
self.custtype = custtype
def HandleCustomer(self):
try:
self.pipeline.send(self)
except StopIteration:
pass
if __name__ == '__main__':
platinum = Customer('platinum')
gold = Customer('gold')
silver = Customer('silver')
diamond = Customer('diamond')
undefined = Customer('undefined')
platinum.HandleCustomer()
gold.HandleCustomer()
undefined.HandleCustomer()
我试图做的,是尽量创造的责任模式解决方案链处理不同类型的客户(白金,黄金,钻石,银)的。
对于该客户有一个管道,我已经提到了处理不同客户的顺序。 Customer()。HandleCustomer将通过流水线发送一个实例,它将检查它的custtype是否匹配,然后相应地处理它,或者将它发送到其后继者(如果可用)
问题:问题是,我运行上面的脚本,它将处理第一个白金客户,但不是黄金或未定义的。我假设这是因为他已经到达发电机的末端。我如何修改代码,以便每次它是客户的新实例时,都会从头开始通过管道?
答
你的协同程序必须永远循环下去,以处理后续的调用,如:
@coroutine
def PlatinumCustomer(successor=None):
while 1: # <---- this is missing from your coroutines
cust = (yield)
if cust.custtype == 'platinum':
print "Platinum Customer"
elif successor is not None:
successor.send(cust)
,并处理了“未定义”类型,你需要一个最终的包罗万象的处理程序:
@coroutine
def UndefinedCustomer():
while 1:
cust = (yield)
print "No such customer type '%s'" % cust.custtype
,并把它添加到您的管道:
pipeline = PlatinumCustomer(GoldCustomer(SilverCustomer(DiamondCustomer(UndefinedCustomer()))))
(A终止UndefinedCustomer处理程序也将让您从协同工作中删除'如果没有后继'代码 - 除终止符外,它们都将有后继者,它们知道它是终止符,不会称为后继符。)
有了这些更改,我可以得到这个从你的测试输出:
Platinum Customer
Gold Customer
No such customer type 'undefined'
此外,为什么在HandleCustomer捕获StopIteration?这个代码应该是足够的:
def HandleCustomer(self):
self.pipeline.send(self)
工程就像一个魅力。 – Rivas 2015-02-23 09:18:24
我很抱歉无法投票。我没有足够的声誉。 – Rivas 2015-02-23 09:18:59