Python设计模式

Python设计模式 - 备忘录模式

2020-02-22  本文已影响0人  jumo

"""

备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

这样以后就可将该对象恢复到原先保存的状态。

跟原型模式很像,不过在原型模式中保存对象的一切,而备忘录模式中只保存恢复时需要的数据。

"""

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)

上一篇下一篇

猜你喜欢

热点阅读