关闭

Python设计模式(二十一)【备忘录模式】

标签: python设计模式
1473人阅读 评论(0) 收藏 举报
分类:

相信是成功的起点,坚持是成功的终点。

# -*- coding: utf-8 -*-
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)

结果:

<NumObj: -1>
<NumObj: 0>
<NumObj: 1>
<NumObj: 2>
-- committed
<NumObj: 3>
<NumObj: 4>
<NumObj: 5>
-- rolled back
<NumObj: 2>
-- now doing stuff ...
-> doing stuff failed!
Traceback (most recent call last):
  File "mementoTest.py", line 96, in <module>
    num_obj.do_stuff()
  File "mementoTest.py", line 51, in transaction
    raise e
  File "mementoTest.py", line 48, in transaction
    return self.method(obj, *args, **kwargs)
  File "mementoTest.py", line 69, in do_stuff
    self.increment()  # <- 将失败并回滚
  File "mementoTest.py", line 64, in increment
    self.value += 1
TypeError: Can't convert 'int' object to str implicitly
<NumObj: 2>
0
0
查看评论

【Java设计模式】之备忘录模式

备忘录(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
  • xiongwt
  • xiongwt
  • 2016-09-09 15:13
  • 426

JAVA设计模式之:备忘录模式

备忘录模式:又叫做快照模式,指在不破坏封装性的前提下,获取到一个对象的内部状态,并在对象之外记录或保存这个状态。在有需要的时候可将该对象恢复到原先保存的状态。我们相当于把对象原始状备份保留,所以叫备忘录模式。 *模式 角色对象组成: 1.发起者对象:负责创建一个备忘录来记录当前对象的内部状态,并...
  • true100
  • true100
  • 2016-01-22 12:26
  • 2636

C++设计模式——备忘录模式

前言 又到年底了,也静不下心来写代码了,大家都很浮躁;翻出经典的《仙剑奇侠传》玩一会;又要打大BOSS,先存一下档吧。这是我的习惯,在打大BOSS之前,都要先存一下档,要是打赢了,就再存一个档,覆盖之前的;如果打输了,就恢复之前的存档,接着重来。我想大家都是这么玩的吧。哎呀,总是打不过。好了,...
  • caoshangpa
  • caoshangpa
  • 2016-10-28 14:35
  • 348

23种设计模式之---备忘录模式

前言网上搜索备忘录设计模式,基本上均是在一个GoF,基础上衍生下来的。为了避免重复造轮子,这里会结合网上demo,和自己理解进行总结定义:备忘录(Memento)模式又称标记(Token)模式。GOF给备忘录模式的定义为:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这...
  • o279642707
  • o279642707
  • 2017-03-07 16:14
  • 633

设计模式---备忘录模式(C++实现)

/********************************************************** 备忘录模式: 就是用一个类来保存一个类的中间状态;;;;; 如果想大规模的保存和管理状态那么就要是用一个管理类------- -------就好比命令模式的时候,命令太多的...
  • alpha_love
  • alpha_love
  • 2017-03-13 13:16
  • 132

Android设计模式(十二)-备忘录模式

备用录模式是一种行为型设计模式,用于保存对象当前的状态,以便之后可以再次恢复到此状态。备忘录模式要保证保存的对象状态不能被对象从外部访问,保护好被保存的这些对象状态的完整性以及内部实现不向外部暴露。定义在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢...
  • qq_25806863
  • qq_25806863
  • 2017-04-05 10:42
  • 600

设计模式学习之备忘录模式:象棋中“悔棋”操作

题目分析:备忘录模式的定义是捕获一个对象的内部状态并在该对象之外保存这个内部状态。从这个模式的定义可知我们需要一个类随时对目标对象的保存和创建进行管理,这个类就是Origintor(发起人)类,同时也用它对当前的状态进行管理,以便随时保存。然后需要一个类CareTaker负责保存好备忘录。 UML...
  • u014293306
  • u014293306
  • 2015-06-23 14:11
  • 1028

大话设计模式—备忘录模式

备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。很多时候我们总是需要记录一个对象的内部状态,这...
  • lmb55
  • lmb55
  • 2016-03-30 20:51
  • 1290

设计模式-行为型之备忘录模式

模式动机   现在大多数软件都有撤销的功能,快捷键一般都是Ctrl+Z,即我们需要提供一种类似“后悔药”的机制,让软件可以回到之前的状态,因此需要保存用户每一次操作时系统的状态,一旦出现误操作,可以把存储的历史状态取出即可回到之前的状态。备忘录模式是一种给我们的软件提供后悔药的机制,通过它可以使系统...
  • ABC374744988
  • ABC374744988
  • 2015-09-16 21:56
  • 317

c++的设计模式之备忘录模式

备忘录模式就是能够存储当前状态,类似于玩游戏的时候可以不断的读档,同时在玩了新的游戏的时候,又可以更新到档案里。 #include #include using namespace std; //需保存的信息 class Memento { public: int m...
  • u013676711
  • u013676711
  • 2015-06-18 20:05
  • 992
    个人资料
    • 访问:1307619次
    • 积分:18727
    • 等级:
    • 排名:第588名
    • 原创:312篇
    • 转载:936篇
    • 译文:123篇
    • 评论:297条
    博客专栏
    文章分类
    打赏
    如果你觉得我的文章对您有用,请随意打赏。 微信 支付宝