设计模式之 Memento - 备忘录模式

Memento模式也叫备忘录模式,是由GoF提出的23种软件设计模式的一种。Memento模式是行为模式之一,它的作用是保存对象的内部状态,并在需要的时候(undo/rollback)恢复对象以前的状态。


本文介绍设计模式中的(Memento)模式的概念,用法,以及实际应用中怎么样使用Memento模式进行开发。
Memento模式的概念
Memento模式是行为模式之一,它的作用是保存对象的内部状态,并在需要的时候(undo/rollback)恢复对象以前的状态。
Memento的英文原意包含有纪念物,快照,备忘录的意思,Memento模式取意使用memento来保存对象现有的状态,从而可以在将来需要的时候把这个对象还原到以前被保存的状态。

Memento模式的角色:
Originator(原生者)
    需要被保存状态以便恢复的那个对象。
Memento(备忘录)
    该对象由Originator创建,主要用来保存Originator的内部状态。
Caretaker(管理者)
    负责在适当的时间保存/恢复Originator对象的状态。


Memento模式的应用场景
如果一个对象需要保存状态并可通过undo或rollback等操作恢复到以前的状态时,可以使用Memento模式。
1)一个类需要保存它的对象的状态(相当于Originator角色)
2)设计一个类,该类只是用来保存上述对象的状态(相当于Memento角色)
3)需要的时候,Caretaker角色要求Originator返回一个Memento并加以保存
4)undo或rollback操作时,通过Caretaker保存的Memento恢复Originator对象的状态


Memento模式的应用范例
Memento模式比较简单,我们只需要按照上面所介绍的步骤就可以实现Memento模式。

下面,我们使用Memento模式模拟下面这个操作:
对字符串做append操作,每操作一次计数器+1,这个操作由Originator类实现;另外,我们需要在适当的时候恢复操作之前的状态加以回退(undo)。
文件一览:
Client
    测试类。
Memento
    Memento备忘录类。保持Originator对象的状态。
Originator
    需要保持/恢复状态的类。该类有2个状态需要保存String data以及int count。
Caretaker
    管理者类,根据情况可以省略。

代码:
public class Client {

     /**
     * Test Memento Pattern
     */

     public static void main(String[] args) {
         //创建目标对象
        Originator org = new Originator();
        org.setData(" aaa");
        System.out.println(" Original value: [" + org.getData() + " , " + org.getCount() + " ]");

         //创建目标对象的一个快照
        Memento snapshot = org.createMemento();
         //通过Caretaker保存此快照
        Caretaker caretaker = new Caretaker();
        caretaker.setMemento(snapshot);

         //操作目标对象改变目标对象的值
        org.append(" bbb");
        org.append(" ccc");
        System.out.println(" Updated value: [" + org.getData() + " , " + org.getCount() + " ]");

        
         //还原
        org.setMemento(caretaker.getMemento());
        System.out.println(" Restored value: [" + org.getData() + " , " + org.getCount() + " ]");
    }

}


/**
* Originator
*
*/

class Originator {
     private String data = "";
     private int count = 0;

     public void append(String expr) {
        data += expr;
        count++;
    }

     public String getData() {
         return data;
    }

     public void setData(String data) {
        this.data = data;
    }

     public Memento createMemento() {
         return new Memento(data, count);
    }

     public void setMemento(Memento memento) {
        data = memento.getData();
        count = memento.getCount();
    }

     public int getCount() {
         return count;
    }

     public void setCount( int count) {
        this.count = count;
    }
}


/**
* Memento
*
*/

class Memento {
     private String data;
     private int count = 0;

     public Memento(String data, int count) {
        this.data = data;
        this.count = count;
    }

     public String getData() {
         return data;
    }
    
     public int getCount() {
         return count;
    }

     public void setCount( int count) {
        this.count = count;
    }
}


/**
* Caretaker
*
*/

class Caretaker {
    Memento memento;

     public Memento getMemento() {
         return memento;
    }

     public void setMemento(Memento memento) {
        this.memento = memento;
    }
}



执行Client,输出结果:
C:\Memento>javac *.java
C:\Memento>java Client
Original value: [aaa, 0]
Updated value: [aaabbbccc, 2]
Restored value: [aaa, 0]
C:\Memento>
Originator对象的初始状态为[aaa, 0],经过某些操作,变为[aaabbb, 2],经过Memento模式处理之后,又复原到了[aaa, 0]。

后记:
1, Command模式也可以用来恢复对象的状态,一般Command模式可以支持多级状态的回退,Memento只是简单的恢复(一级);其实,Command模式在每一个undo中,可以使用Memento来保存对象的状态。
- Command can use Memento to maintain the state required for an undo operation. [GoF, p242]
2,从Originator对象到Memento的过程是一个对象拷贝的操作, Java语言的克隆与深层次克隆技术入门与精通 一文比较深入地介绍了对象间的拷贝技术。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值