Python版
https://github.com/faif/python-patterns/blob/master/behavioral/chain.py
#!/usr/bin/env python
"""
http://www.dabeaz.com/coroutines/
"""
from contextlib import contextmanager
import os
import sys
import time
import abc
class Handler(object):
__metaclass__ = abc.ABCMeta
def \_\_init\_\_(self, successor=None):
self.\_successor = successor
def handle(self, request):
res = self.\_handle(request)
if not res:
self.\_successor.handle(request)
@abc.abstractmethod
def \_handle(self, request):
raise NotImplementedError('Must provide implementation in subclass.')
class ConcreteHandler1(Handler):
def \_handle(self, request):
if 0 < request <= 10:
print('request {} handled in handler 1'.format(request))
return True
class ConcreteHandler2(Handler):
def \_handle(self, request):
if 10 < request <= 20:
print('request {} handled in handler 2'.format(request))
return True
class ConcreteHandler3(Handler):
def \_handle(self, request):
if 20 < request <= 30:
print('request {} handled in handler 3'.format(request))
return True
class DefaultHandler(Handler):
def \_handle(self, request):
print('end of chain, no handler for {}'.format(request))
return True
class Client(object):
def \_\_init\_\_(self):
self.handler = ConcreteHandler1(
ConcreteHandler3(ConcreteHandler2(DefaultHandler())))
def delegate(self, requests):
for request in requests:
self.handler.handle(request)
def coroutine(func):
def start(*args, **kwargs):
cr = func(*args, **kwargs)
next(cr)
return cr
return start
@coroutine
def coroutine1(target):
while True:
request = yield
if 0 < request <= 10:
print('request {} handled in coroutine 1'.format(request))
else:
target.send(request)
@coroutine
def coroutine2(target):
while True:
request = yield
if 10 < request <= 20:
print('request {} handled in coroutine 2'.format(request))
else:
target.send(request)
@coroutine
def coroutine3(target):
while True:
request = yield
if 20 < request <= 30:
print('request {} handled in coroutine 3'.format(request))
else:
target.send(request)
@coroutine
def default_coroutine():
while True:
request = yield
print('end of chain, no coroutine for {}'.format(request))
class ClientCoroutine:
def \_\_init\_\_(self):
self.target = coroutine1(coroutine3(coroutine2(default\_coroutine())))
def delegate(self, requests):
for request in requests:
self.target.send(request)
def timeit(func):
def count(\*args, \*\*kwargs):
start = time.time()
res = func(\*args, \*\*kwargs)
count.\_time = time.time() - start
return res
return count
@contextmanager
def suppress_stdout():
try:
stdout, sys.stdout = sys.stdout, open(os.devnull, 'w')
yield
finally:
sys.stdout = stdout
if __name__ == "__main__":
client1 = Client()
client2 = ClientCoroutine()
requests = [2, 5, 14, 22, 18, 3, 35, 27, 20]
client1.delegate(requests)
print('-' \* 30)
client2.delegate(requests)
requests \*= 10000
client1\_delegate = timeit(client1.delegate)
client2\_delegate = timeit(client2.delegate)
with suppress\_stdout():
client1\_delegate(requests)
client2\_delegate(requests)
# lets check which is faster
print(client1\_delegate.\_time, client2\_delegate.\_time)
Python版
手机扫一扫
移动阅读更方便
你可能感兴趣的文章