简介:备忘录模式保存一个对象的某个状态,以便在适当的时候根据某一状态恢复对象。备忘录模式属于行为型模式。
应用实例:①游戏存档。②Windows 里的 ctri + z撤销。③浏览器中的后退。④数据库事物中的回滚。
结构:
发起者角色(Originator):负责创建一个备忘录用以记录当前时刻它的内部状态,并可以使用备忘录恢复内部状态。
备忘录角色(Memento):负责存储Originator对象的内部状态,并可以防止Originator以外的其他对象访问备忘录。
管理者角色(CareTake):负责保存好备忘录。
自己理解:
①备忘录角色:可以获取对象(发起者角色对象,通俗来讲就是需要备忘的对象)的所有状态,例如游戏中的时间,分值等信息。所以常见备忘录对象时,需要发起者角色对象的所有状态。通常可以在备忘录角色构造方法中传入一个发起者角色对象以此获取所有状态。
②发起者角色(需要备忘的对象):一般需要提供可以备忘的方法(返回一个备忘录角色对象)和从备忘录中回去原对象的方法(一般需要一个备忘录角色对象作为方法参数)
下面的代码是关于游戏存档的。
/**
*备忘录角色,保存游戏的状态
*/
public class GameMemento {
private String name;
private Integer score;
private String time;
/**
* 构造方法的参数是一个Game对象,这样就将Game的状态全部保存到备忘录中了。
*/
public GameMemento(Game game){
this.name=game.getName();
this.score=game.getScore();
this.time=game.getTime();
}
public String getName() {
return name;
}
public Integer getScore() {
return score;
}
public String getTime() {
return time;
}
}
/**
*发起者角色,游戏
*/
class Game{
private String name;
private Integer score;
private String time;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getScore() {
return score;
}
public void setScore(Integer score) {
this.score = score;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public Game(String name, Integer score, String time) {
super();
this.name = name;
this.score = score;
this.time = time;
}
@Override
public String toString() {
return "Game [name=" + name + ", score=" + score + ", time=" + time + "]";
}
/**
* 提供备忘的方法,返回备忘录对象
*/
public GameMemento saveGame(){
return new GameMemento(this);
}
/**
* 根据备忘录对象,将原对象的状态还原到备份时的状态
*/
public void recoveryGame(GameMemento memento){
this.name=memento.getName();
this.score=memento.getScore();
this.time=memento.getTime();
}
/**
* 根据备忘录对象,创建一个新的对象,该对象和原发起者对象的状态保持一致。这种方式用于发起者对象可能被回收的情况下。
* 如果不想创建新对象,可以使用对象克隆的方式(原型模式)
*/
public Game recoveryNewGame(GameMemento memento){
Game game=new Game(memento.getName(),memento.getScore(),memento.getTime());
return game;
}
}
/**
*管理者角色,对备忘录进行管理。如游戏的保存,可能有很多的保存节点,就需要专门的类对保存记录进行管理。
*这里是个简单的List集合,实际中可以使用Map集合快速查找备忘录。
*/
class CareTaker{
private List<GameMemento> mementos=new ArrayList<>();
public void addMemento(GameMemento memento){
mementos.add(memento);
}
public GameMemento getMemento(int index){
return mementos.get(index);
}
}
主方法:
public class Main {
public static void main(String[] args) {
//为了程序的简介,这里不使用CareTaker对备忘录对象进行管理。实际开发中根据需求使用。这里只是简单的演示
CareTaker careTaker=new CareTaker();
Game game=new Game("出山", 10, "2018.5.6");
//进行备份
GameMemento gMemento=game.saveGame();
//对原对象进行修改
game.setTime("2018.5.8");
//根据备忘录角色对象,恢复Game对象
game.recoveryGame(gMemento);
System.err.println(game);
}
}
运行结果:
Game [name=出山, score=10, time=2018.5.6]
参考文章:
Java设计模式20-备忘录模式