本文最后更新于:3 years ago
备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于 行为型模式
如果想了解备忘录模式的具体的介绍,菜鸟教程介绍得比较详细↓
菜鸟教程-备忘录模式
结构图
优缺点
优点:
1、给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。
2、实现了信息的封装,使得用户不需要关心状态的保存细节。
缺点:
消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。
使用场景
1、需要保存/恢复数据的相关状态场景。
2、提供一个可回滚的操作。
实现代码
这个模式比较好理解,就比如说我们在玩游戏的时候,你存了档,然后进行回档的话,其实就是备忘录模式
Windows中我们常用的Ctrl+z也就是这个模式。
Memento
模式中Originator
是发起人,负责创建一个备忘录Memento
,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态;Memento
是备忘录,负责存储Originator
对象的内部状态,并可防止Originator
以外的其他对象访问备忘录Memento
;Caretaker
是管理者,负责保存好备忘录的Memento
,不能对备忘录的内容进行操作或检查。
模拟一个小游戏,我们让一个兔子进行随机的运动,每当一个时刻,我们就记录它的位置,
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| public class Main {
public static void main(String[] args) { Originator originator = new Originator(); CareTaker careTaker = new CareTaker(); Rabbit rabbit = new Rabbit(10, 20); for (int i = 0; i < 10; i++) { switch ((int) (Math.random() * 10) % 4) { case 0: rabbit.x += 5; break; case 1: rabbit.x -= 5; break; case 2: rabbit.y += 5; break; case 3: rabbit.y -= 5; break; default: System.out.println("no"); break; }
if (i % 3 == 0) { originator.setState(rabbit.toString()); careTaker.add(originator.saveStateToMemento()); } } for (int j = 0; j < 3; j++) { originator.getStateFromMemento(careTaker.get(j)); System.out.println(j + " --> " + originator.getState()); } }
}
public class Rabbit { int x; int y;
public Rabbit(int x, int y) { this.x = x; this.y = y; }
@Override public String toString() { return "Rabbit{" + "x=" + x + ", y=" + y + '}'; } }
public class Memento { private String state;
public Memento(String state) { this.state = state; }
public String getState() { return state; } }
public class Originator { private String state;
public String getState() { return state; }
public void setState(String state) { this.state = state; }
public Memento saveStateToMemento(){ return new Memento(state); }
public void getStateFromMemento(Memento Memento){ state = Memento.getState(); } }
public class CareTaker { private List<Memento> mementoList = new ArrayList<Memento>(); public void add(Memento state){ mementoList.add(state); } public Memento get(int index){ return mementoList.get(index); }
public int getSize(){ return mementoList.size(); } }
|
输出结果:
| 0 --> Rabbit{x=5, y=20} 1 --> Rabbit{x=5, y=25} 2 --> Rabbit{x=10, y=25}
|
输出结果就是记录着Rabbit的移动轨迹。
当我们在存档的时候,需要将当前的数据保存起来,保存的数据就存在Originator
中
如果我们想要读档的时候,那么将Originator
中的数据读出即可,并且,读档的功能也是通过Originator
实现的
但是我们存档当然不可能就是存一个,多个存档就需要存储在CareTaker
中
这就是备忘录的基本思想,这个模式在开发的时候还是用得比较多的模式,需要好好理解一下