Python设计模式 - 备忘录模式
"""
备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
这样以后就可将该对象恢复到原先保存的状态。
跟原型模式很像,不过在原型模式中保存对象的一切,而备忘录模式中只保存恢复时需要的数据。
"""
from copy import copy, deepcopy
def memento(obj, deep=False):
state = deepcopy(obj.__dict__) if deep else copy(obj.__dict__)
def restore():
obj.__dict__.clear()
obj.__dict__.update(state)
return restore
class Transaction:
"""
一个事务守护.
这一点,事实上, 就是语法糖 around a memento closure.
"""
deep = False
states = []
def __init__(self, deep, *targets):
self.deep = deep
self.targets = targets
self.commit()
def commit(self):
self.states = [memento(target, self.deep) for target in self.targets]
def rollback(self):
for a_state in self.states:
a_state()
class Transactional(object):
"""
添加事务语义方法。方法用@Transactional装饰,在异常时将回滚到进入状态。
"""
def __init__(self, method):
self.method = method
def __get__(self, obj, T):
def transaction(*args, **kwargs):
state = memento(obj)
try:
return self.method(obj, *args, **kwargs)
except Exception as e:
state()
raise e
return transaction
class NumObj(object):
def __init__(self, value):
self.value = value
def __repr__(self):
return '<%s: %r>' % (self.__class__.__name__, self.value)
def increment(self):
self.value += 1
@Transactional
def do_stuff(self):
self.value = '1111' # <- 无效的值
self.increment() # <- 将失败并回滚
if __name__ == '__main__':
num_obj = NumObj(-1)
print(num_obj)
a_transaction = Transaction(True, num_obj)
try:
for i in range(3):
num_obj.increment()
print(num_obj)
a_transaction.commit()
print('-- committed')
for i in range(3):
num_obj.increment()
print(num_obj)
num_obj.value += 'x' # 将失败
print(num_obj)
except Exception as e:
a_transaction.rollback()
print('-- rolled back')
print(num_obj)
print('-- now doing stuff ...')
try:
num_obj.do_stuff()
except Exception as e:
print('-> doing stuff failed!')
import sys
import traceback
traceback.print_exc(file=sys.stdout)
print(num_obj)