设计模式学习笔记

备忘录模式

备忘录模式能记录一个对象,当用户后悔时能撤销当前的操作,使数据恢复到它上一步的状态,在生活中有很多常见例子,如文本编辑器,游戏的存档。

假设我们要实现一个编辑器,那应该怎样实现这个功能呢? 比较好的一个方式就是:程序在执行操作时先获得编辑器对象的状态快照并保存,后可以通过快照将对象恢复到之前的状态。

那我们应该怎么创建这些状态快照呢?最粗暴的方法就是,遍历对象的所有变量并复制保存,但从外部访问要求对象的内容没有访问权限限制,这样就破坏了对象的封闭性。 并且,当对象内部增加成员时, 代码变得难以维护。

备忘录的最佳实践,是既然我们没有办法从外部获取对象的快照,那我们可以直接将生成快照的义务交给本对象(原发器Originator),其他对象也不需要关系本对象的内部细节。

生成的快照我们将它放到另外一个类Memento,这个类负责存储过去生成的快照,并在需要时能获取过去的快照版本。

值得注意的是,Memento并没有权限访问快照中的数据,其他对象必须通过接口访问备忘录中的数据。

同时, 原发器拥有对备忘录所有成员的访问权限, 从而能随时恢复其以前的状态。

  1. 原发器 (Originator) 类可以生成自身状态的快照, 也可以在需要时通过快照恢复自身状态。
  2. 备忘录 (Memento) 是原发器状态快照的值对象 (value object)。 通常做法是将备忘录设为不可变的, 并通过构造函数一次性传递数据。
  3. 负责人 (Caretaker) 仅知道 “何时” 和 “为何” 捕捉原发器的状态, 以及何时恢复状态。
Java实现

步骤:
1. 创建文本编辑器,它具有生成自己快照的功能 ,快照包括了它自身的成员变量和数据(两个类,编辑器类和快照类)
2. 将生成的快照保存到备忘录类(负责人) ,负责人只负责存储和取出状态。
3. 当编译器想要撤回时,只需要从备忘录中获得那一版本的快照,再获取快照中的数据。

编辑器类:(原发器)

class editor {
    private String content ; /**user content*/ 
    public void edit(String content ) {
        this.content=content ;
    }
    public snapShot createSnapShot(){
        return new snapShot(this.content) ; 
    }
    public void restore(snapShot snapshot) {
        content = snapshot.getContent() ; 
    }
    public void print() {
        System.out.println("现在的内容是:" + content) ; 
    }
}

快照类 (备忘录)

public class snapShot {
    private final String content ;
    snapShot(String content) {
        this.content=content; 
    }

    public String getContent(){
        return content ; 
    }

}

备忘录类: (负责人CareTaker)

import java.util.ArrayList;
import java.util.List;
public class memento {
    private List<snapShot> memento = new ArrayList<>() ;
    public void push(snapShot snapshot) {
        memento.add(snapshot) ;
    }
    public snapShot pop(){
        int lastIndex = memento.size()-1 ;
        snapShot lastSnapShot =memento.get(lastIndex) ;
        memento.remove(lastSnapShot); 
        return lastSnapShot; 
    }
}

测试:

public class Main {
    public  static void main(String args[]){
        editor e =new editor() ;
        memento historyMemento = new memento() ;
        
        e.edit("Hello world"); /**编辑内容 */
        snapShot  snapShot = e.createSnapShot(); /**创建快照 */
        historyMemento.push(snapShot); /**将快照保存到备忘录里*/
        e.print() ;

        e.edit("哎呀写错啦") ;
        historyMemento.push(e.createSnapShot());
        e.print() ;

        e.edit("撤回撤回");
        historyMemento.push(e.createSnapShot()) ; 
        e.print() ;

        e.restore(historyMemento.pop()); /**恢复到上一个内容 */ 
        e.print() ;

        e.restore(historyMemento.pop()); /**恢复到上一个内容 */ 
        e.print() ;
    } 
}

参考文章: Click here

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值