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

2020-01-31  本文已影响0人  远行_2a22

Chain of Resposibility(职责链)

动机(Motivation)

模式定义

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

要点总结

例子

# -*- 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()
--------------------
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
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
上一篇 下一篇

猜你喜欢

热点阅读