【编程思想】【设计模式】【行为模式Behavioral】chain
阅读原文时间:2023年07月08日阅读:3

Python版

https://github.com/faif/python-patterns/blob/master/behavioral/chain.py

#!/usr/bin/env python

-*- coding: utf-8 -*-

"""
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)

OUTPUT ###

request 2 handled in handler 1

request 5 handled in handler 1

request 14 handled in handler 2

request 22 handled in handler 3

request 18 handled in handler 2

request 3 handled in handler 1

end of chain, no handler for 35

request 27 handled in handler 3

request 20 handled in handler 2

------------------------------

request 2 handled in coroutine 1

request 5 handled in coroutine 1

request 14 handled in coroutine 2

request 22 handled in coroutine 3

request 18 handled in coroutine 2

request 3 handled in coroutine 1

end of chain, no coroutine for 35

request 27 handled in coroutine 3

request 20 handled in coroutine 2

(0.2369999885559082, 0.16199994087219238)

Python版

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章