美文网首页
设计模式(python实现)--职责链模式(Chain of R

设计模式(python实现)--职责链模式(Chain of R

作者: 远行_2a22 | 来源:发表于2020-01-31 13:53 被阅读0次

    Chain of Resposibility(职责链)

    动机(Motivation)

    • 让多个对象来处理单个请求
    • 预先不知道应该由哪个对象(来自某个对象链)来处理某个特定请求时。

    模式定义

    使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
    ——《设计模式》GoF

    要点总结

    • 原则如下所示。
      (1) 存在一个对象链(链表、树或任何其他便捷的数据结构)。
      (2) 我们一开始将请求发送给链中的第一个对象。
      (3) 对象决定其是否要处理该请求。
      (4) 对象将请求转发给下一个对象。
      (5) 重复该过程,直到到达链尾。
    • 客户端代码仅知道第一个处理元素,而非拥有对所有处理元素的引用;并且每个处理 元素仅知道其直接的下一个邻居(称为后继),而不知道所有其他处理元素。这通常是一种单向关系,用编程术语来说是一个单向链表。
    • 职责链一定程度上可以用单向链表来代替,现在用的较少。

    例子

    # -*- coding:utf-8 -*-
    
    class ChainType(object):
        Success_To_Next = 0  # 当前节点执行成功后传递到下一个
        Fail_To_Next = 1  # 当前节点执行失败后传递到下一个
        To_Next = 2  # 直接传递给下一个
    
    
    class Event(object):
        def __init__(self, name):
            self.name = name
    
        def __str__(self):
            return self.name
    
    
    class Widget(object):
        def __init__(self):
            self.next_chain = None
    
        def handle(self, event, handle_type=ChainType.To_Next):
            flag = self.process_event(event)
            if (handle_type == ChainType.Success_To_Next and flag) or \
                (handle_type == ChainType.Fail_To_Next and not flag) or \
                    handle_type == ChainType.To_Next:
                if self.next_chain:
                    print('cur_chain:%s finish, next chain:%s start' % (self.__class__.__name__, self.next_chain.__class__.__name__))
                    self.next_chain.handle(event, handle_type)
    
        def process_event(self, event):
            handler = 'handle_{}'.format(event)
            print('%s start process event:%s' % (self.__class__.__name__, handler))
    
            flag = True
            if hasattr(self, handler):
                # 对象有该event接口直接执行
                method = getattr(self, handler)
                method(event)
            elif hasattr(self, 'handle_default'):
                # 否则该对象有handle_default接口
                self.handle_default(event)
            else:
                # 否则不执行
                print('%s process failed, abandon it' % self.__class__.__name__)
                flag = False
            return flag
    
        def set_next_chain(self, next_chain):
            self.next_chain = next_chain
    
    
    class MainWindow(Widget):
        def handle_close(self, event):
            print('MainWindow: {}'.format(event))
    
    
    class SendDialog(Widget):
        def handle_paint(self, event):
            print('SendDialog: {}'.format(event))
    
    
    class MsgText(Widget):
        def handle_down(self, event):
            print('MsgText: {}'.format(event))
    
        def handle_default(self, event):
            print('MsgText Default: {}'.format(event))
    
    
    def main():
        main_window = MainWindow()
        send_dialog = SendDialog()
        msg_text = MsgText()
    
        main_window.set_next_chain(send_dialog)
        send_dialog.set_next_chain(msg_text)
    
        for e in ('down', 'paint', 'close'):
            print('-' * 20)
            evt = Event(e)
            main_window.handle(evt, handle_type=ChainType.Fail_To_Next)
    
    if __name__ == '__main__':
        main()
    
    • 类型为ChainType.Fail_To_Next, 即当前节点处理失败后才发送给下一个节点。输出为
    --------------------
    MainWindow start process event:handle_down
    MainWindow process failed, abandon it
    cur_chain:MainWindow finish, next chain:SendDialog start
    SendDialog start process event:handle_down
    SendDialog process failed, abandon it
    cur_chain:SendDialog finish, next chain:MsgText start
    MsgText start process event:handle_down
    MsgText: down
    --------------------
    MainWindow start process event:handle_paint
    MainWindow process failed, abandon it
    cur_chain:MainWindow finish, next chain:SendDialog start
    SendDialog start process event:handle_paint
    SendDialog: paint
    --------------------
    MainWindow start process event:handle_close
    MainWindow: close
    
    • 类型为ChainType.To_Next, 即当前节点处理成功与否都发送给下一个节点。输出为
    MainWindow start process event:handle_down
    MainWindow process failed, abandon it
    cur_chain:MainWindow finish, next chain:SendDialog start
    SendDialog start process event:handle_down
    SendDialog process failed, abandon it
    cur_chain:SendDialog finish, next chain:MsgText start
    MsgText start process event:handle_down
    MsgText: down
    --------------------
    MainWindow start process event:handle_paint
    MainWindow process failed, abandon it
    cur_chain:MainWindow finish, next chain:SendDialog start
    SendDialog start process event:handle_paint
    SendDialog: paint
    cur_chain:SendDialog finish, next chain:MsgText start
    MsgText start process event:handle_paint
    MsgText Default: paint
    --------------------
    MainWindow start process event:handle_close
    MainWindow: close
    cur_chain:MainWindow finish, next chain:SendDialog start
    SendDialog start process event:handle_close
    SendDialog process failed, abandon it
    cur_chain:SendDialog finish, next chain:MsgText start
    MsgText start process event:handle_close
    MsgText Default: close
    

    相关文章

      网友评论

          本文标题:设计模式(python实现)--职责链模式(Chain of R

          本文链接:https://www.haomeiwen.com/subject/nldgthtx.html