美文网首页
设计模式(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