責任鏈模式
1、內容
使多個物件都有機會處理請求,從而避免請求的傳送者和接受者之間的耦合關係。將這些物件連成一條鏈,並沿著這條鏈傳遞該請求
直到有一個物件處理它為止
2、角色
抽象處理者
具體處理者
客戶端
例:請假部門批准:專案主管----》部門經理----》總經理
3、使用場景
有多個物件可以處理一個請求,哪個物件處理由時間執行時決定
在不明確接受者的情況下,向多個物件中的一個提交一個請求
4、優點
降低耦合度:一個物件無需知道是其他哪一個物件處理其請求
複製程式碼
5、缺點
請求不保證被接收:鏈的末端沒有處理或者鏈配置錯誤
6、程式碼示例
請假示例
from abc import ABCMeta, abstractmethod
#
class Handler(metaclass=ABCMeta):
@abstractmethod
def handle_leave(self, day):
pass
class GeneralManagerHandler(Handler):
def handle_leave(self, day):
if day < 10:
print("總經理批准%d天假"%day)
else:
print("呵呵")
class DepartmentManagerHandler(Handler):
def __init__(self):
self.successor = GeneralManagerHandler() #責任鏈的後面的一個人
def handle_leave(self, day):
if day < 7:
print("部門經理批准%d天假"%day)
else:
print("部門經理無權准假")
self.successor.handle_leave(day)
class ProjectDirectorHandler(Handler):
def __init__(self):
self.successor = DepartmentManagerHandler()
def handle_leave(self, day):
if day < 3:
print("專案主管批准%d天假")
else:
print("專案主管無權准假")
self.successor.handle_leave(day)
day = 4
h = ProjectDirectorHandler()
h.handle_leave(day)
複製程式碼
模仿js事件處理
#--高階例子--模仿js事件處理
# JavaScript中假如有三個巢狀的div,每個div繫結一個事件,就像冒泡一樣,先找裡面的,
# 如果裡面有就是裡面的事件,如果裡面沒有就找上一層的。以此類推
from abc import ABCMeta, abstractmethod
class Handler(metaclass=ABCMeta):
@abstractmethod
def add_event(self, func):
pass
@abstractmethod
def handle(self):
pass
class BodyHandler(Handler):
def __init__(self):
self.func = None
def add_event(self, func):
self.func = func
def handle(self):
if self.func:
return self.func()
else:
print("已到最後一級,無法處理")
class ElementHandler(Handler):
def __init__(self, successor):
self.func = None
self.successor = successor
def add_event(self, func):
self.func = func
def handle(self):
if self.func:
return self.func()
else:
return self.successor.handle()
# 客戶端
# <body><div><a>
body = {'type': 'body', 'name': 'body', 'children': [], 'father': None}
div = {'type': 'div', 'name': 'div', 'children': [], 'father': body}
a = {'type': 'a', 'name': 'a', 'children': [], 'father': div}
body['children'].append(div)
div['children'].append(a)
body['event_handler'] = BodyHandler()
div['event_handler'] = ElementHandler(div['father']['event_handler'])
a['event_handler'] = ElementHandler(a['father']['event_handler'])
def attach_event(element, func):
element['event_handler'].add_event(func)
#test
def func_div():
print("這是給div的函式")
def func_a():
print("這是給a的函式")
def func_body():
print("這是給body的函式")
# attach_event(div, func_div)
attach_event(a, func_a)
# attach_event(body, func_body)
a['event_handler'].handle()
複製程式碼