使用协程在 python 中实施责任链模式
Implementing Chain of responsibility pattern in python using coroutines
我正在探索 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 将通过管道发送自己的一个实例,管道将检查其客户类型是否匹配,然后进行相应处理,或者将其发送给其继任者(如果可用)
问题:问题是当我运行上面的脚本时,它会处理第一个白金客户而不是黄金或未定义的。我假设这是因为他已经到达发电机的末端。我如何修改代码,以便每次它是客户的新实例时,它都会从头开始通过管道?
您的协程必须永远循环才能处理连续调用,如:
@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)
要处理 'undefined' 类型,您需要一个最终的包罗万象的处理程序:
@coroutine
def UndefinedCustomer():
while 1:
cust = (yield)
print "No such customer type '%s'" % cust.custtype
并将其添加到您的管道中:
pipeline = PlatinumCustomer(GoldCustomer(SilverCustomer(DiamondCustomer(UndefinedCustomer()))))
(终止 UndefinedCustomer 处理程序还允许您从协程中删除 'if there is no successor' 代码 - 除了终止符之外,所有代码都将有后继程序,它知道它是终止程序并且不会调用后继程序。 )
通过这些更改,我从您的测试中得到了以下输出:
Platinum Customer
Gold Customer
No such customer type 'undefined'
此外,为什么要捕获 HandleCustomer 中的 StopIteration?此代码应该足够了:
def HandleCustomer(self):
self.pipeline.send(self)
我正在探索 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 将通过管道发送自己的一个实例,管道将检查其客户类型是否匹配,然后进行相应处理,或者将其发送给其继任者(如果可用)
问题:问题是当我运行上面的脚本时,它会处理第一个白金客户而不是黄金或未定义的。我假设这是因为他已经到达发电机的末端。我如何修改代码,以便每次它是客户的新实例时,它都会从头开始通过管道?
您的协程必须永远循环才能处理连续调用,如:
@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)
要处理 'undefined' 类型,您需要一个最终的包罗万象的处理程序:
@coroutine
def UndefinedCustomer():
while 1:
cust = (yield)
print "No such customer type '%s'" % cust.custtype
并将其添加到您的管道中:
pipeline = PlatinumCustomer(GoldCustomer(SilverCustomer(DiamondCustomer(UndefinedCustomer()))))
(终止 UndefinedCustomer 处理程序还允许您从协程中删除 'if there is no successor' 代码 - 除了终止符之外,所有代码都将有后继程序,它知道它是终止程序并且不会调用后继程序。 )
通过这些更改,我从您的测试中得到了以下输出:
Platinum Customer
Gold Customer
No such customer type 'undefined'
此外,为什么要捕获 HandleCustomer 中的 StopIteration?此代码应该足够了:
def HandleCustomer(self):
self.pipeline.send(self)