備忘錄已维,定義是:在不破壞封閉的前提下淆攻,捕獲一個對象的內部狀態(tài)阔墩,并在該對象之外保存這個狀態(tài)。這樣以后就可將該對象恢復到原先保存的狀態(tài)瓶珊。簡單來說在運行過程中我們可以記錄某個狀態(tài)啸箫,當遇到錯誤時恢復當前狀態(tài),這在業(yè)務流程中是用設計來處理異常情況伞芹。
示例code:
class AddNumber:
def __init__(self):
self.start = 1
def add(self, number):
self.start += number
print(self.start)
class Memento:
"""備忘錄"""
def backups(self, obj=None):
"""
設置備份方法
:param obj:
:return:
"""
self.obj_dict = copy.deepcopy(obj.__dict__)
print("備份數據:{}".format(self.obj_dict))
def recovery(self, obj):
"""
恢復備份方法
:param obj:
:return:
"""
obj.__dict__.clear()
obj.__dict__.update(self.obj_dict)
return obj
if __name__ == '__main__':
test = AddNumber()
memento = Memento()
for i in [1, 2, 3, 'n', 4]:
if i == 2:
memento.backups(test)
try:
test.add(i)
except TypeError as e:
print(e)
print(test.start)
memento.recovery(test)
print(test.start)
--------------------
2
備份數據:{'start': 2}
4
7
unsupported operand type(s) for +=: 'int' and 'str'
7
11
2
上面案例是不嚴謹的忘苛,意在闡述備忘錄的思想,實際中完整的備忘錄應該有三個重要角色:
1.Originator(發(fā)起人):負責創(chuàng)建一個備忘錄Memento唱较,用以記錄當前時刻自身的內部狀態(tài)扎唾,并可使用備忘錄恢復內部狀態(tài)。Originator可以根據需要決定Memento存儲自己的哪些內部狀態(tài)南缓。
2.Memento(備忘錄):負責存儲Originator對象的內部狀態(tài)胸遇,并可以防止Originator以外的其他對象訪問備忘錄。備忘錄有兩個接口:Caretaker只能看到備忘錄的窄接口汉形,他只能將備忘錄傳遞給其他對象纸镊。Originator卻可看到備忘錄的寬接口,允許它訪問返回到先前狀態(tài)所需要的所有數據概疆。
3.Caretaker(管理者):負責備忘錄Memento逗威,不能對Memento的內容進行訪問或者操作。
備忘錄模式的優(yōu)點和缺點
一岔冀、備忘錄模式的優(yōu)點
1庵楷、有時一些發(fā)起人對象的內部信息必須保存在發(fā)起人對象以外的地方,但是必須要由發(fā)起人對象自己讀取楣颠,這時尽纽,
使用備忘錄模式可以把復雜的發(fā)起人內部信息對其他的對象屏蔽起來,從而可以恰當地保持封裝的邊界童漩。
2弄贿、本模式簡化了發(fā)起人類。發(fā)起人不再需要管理和保存其內部狀態(tài)的一個個版本矫膨,客戶端可以自行管理他們所需
要的這些狀態(tài)的版本差凹。
3期奔、當發(fā)起人角色的狀態(tài)改變的時候,有可能這個狀態(tài)無效危尿,這時候就可以使用暫時存儲起來的備忘錄將狀態(tài)復原呐萌。
二、備忘錄模式的缺點:
1谊娇、如果發(fā)起人角色的狀態(tài)需要完整地存儲到備忘錄對象中肺孤,那么在資源消耗上面?zhèn)渫泴ο髸馨嘿F。
2济欢、當負責人角色將一個備忘錄 存儲起來的時候赠堵,負責人可能并不知道這個狀態(tài)會占用多大的存儲空間,從而無法提醒用戶一個操作是否很昂貴法褥。
3茫叭、當發(fā)起人角色的狀態(tài)改變的時候,有可能這個協(xié)議無效半等。如果狀態(tài)改變的成功率不高的話揍愁,不如采取“假如”協(xié)議模式。