• 【编程思想】【设计模式】【行为模式Behavioral】chain


    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版
  • 相关阅读:
    JS变量的作用域
    使用jquery修改css中带有!important的样式属性
    js异步加载的三种解决方案
    js 停止事件冒泡 阻止浏览器的默认行为(阻止超连接 # )
    【翻译】MongoDB指南/CRUD操作(二)
    【翻译】MongoDB指南/CRUD操作(一)
    【翻译】MongoDB指南/引言
    深入浅出UML类图(一)
    让thinkphp 5 支持pathinfo 的 nginx ,去掉index.php
    linux 常用命令
  • 原文地址:https://www.cnblogs.com/demonzk/p/9035584.html
Copyright © 2020-2023  润新知