Python設計模式 - 備忘錄模式

"""

備忘錄模式:在不破壞封裝性的前提下,捕獲一個對象的內(nèi)部狀態(tài),并在該對象之外保存這個狀態(tài)。

這樣以后就可將該對象恢復到原先保存的狀態(tài)。

跟原型模式很像,不過在原型模式中保存對象的一切,而備忘錄模式中只保存恢復時需要的數(shù)據(jù)。

"""

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裝飾,在異常時將回滾到進入狀態(tài)。

????"""

????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)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容