【Java】我所知道设计模式之备忘录模式

我所知道设计模式备忘录模式

28640发布于 今天 01:46

前言介绍


接下里介绍的是Java 的设计模式之一:备忘录模式

我们还是以一个问题进行展开,引入备忘录模式

当前有一个游戏程序,玩家操控游戏角色,角色有攻击力和防御力,在大战 Boss 前需要保存自身的状态(攻击力和防御力),当大战 Boss 后可能会造成攻击力和防御力下降,这时需要恢复战前的状态

那么你会怎么解决这个问题?

一、传统方式解决问题

【Java】我所知道设计模式之备忘录模式

一个角色对应一个类的类,若游戏角色过多,则会有很多的类造成不利于开销与管理

传统的方式的问题分析

一个对象,就对应一个保存对象状态的对象,这样当我们游戏的对象很多时,不利于管理,开销也很大

传统的方式是简单地做备份,new 出另外一个对象出来,再把需要备份的数据放到这个新对象,但这就暴露了对象内部的细节

我们推荐使用:备忘录模式解决这个问题

二、什么是备忘录模式


备忘录模式(Memento Pattern)在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态

这样以后就可将该对象恢复到原先保存的状态

现实生活中的备忘录是用来记录某些要去做的事情,或者是记录已经达成的共同意见的事情,以防忘记了

在软件层面,备忘录模式有着相同的含义,备忘录对象主要用来记录一个对象的某种状态,或者某些数据,当要做回退时,可以从备忘录对象里获取原来的数据进行恢复操作

备忘录原理类图

【Java】我所知道设计模式之备忘录模式

originator :对象(需要保存状态的对象)
Memento :备忘录对象,负责保存好记录,即 Originator 内部状态
Caretaker:守护者对象,负责保存多个备忘录对象, 使用集合管理,提高效率

说明:如果希望保存多个 originator 对象的不同时间的状态,也可以,只需要要 HashMap <String, 集合>

三、使用备忘录解决问题

【Java】我所知道设计模式之备忘录模式

根据思路,我们先开始创建与原始对象游戏角色的备忘录

//备忘录Memento

class Memento {

//攻击力

private int vit;

//防御力

private int def;

public Memento(int vit, int def) {

super();

this.vit = vit;

this.def = def;

}

public int getVit() {return vit;}

public void setVit(int vit) {this.vit = vit;}

public int getDef() {return def;}

public void setDef(int def) {this.def = def; }

}

接着创建原始对象游戏角色,攻击力、防御力

class GameRole {

//攻击力

private int vit;

//防御力

private int def;

//创建 Memento ,即根据当前的状态得到 Memento

public Memento createMemento() {

return new Memento(vit, def);

}

//从备忘录对象,恢复 GameRole 的状态

public void recoverGameRoleFromMemento(Memento memento) {

this.vit = memento.getVit();

this.def = memento.getDef();

}

//显示当前游戏角色的状态

public void display() {

System.out.println("游戏角色当前的攻击力:" + this.vit + " 防御力: " + this.def);

}

public int getVit() {return vit;}

public void setVit(int vit) { this.vit = vit;}

public int getDef() { return def;}

public void setDef(int def) { this.def = def;}

}

接下来创建管理多个备忘录的守护者类

//守护者对象, 保存游戏角色的状态

class Caretaker {

//如果只保存一次状态

private Memento memento;

//对 GameRole 保存多次状态

private ArrayList<Memento> mementos;

//对多个游戏角色保存多个状态

private HashMap<String, ArrayList<Memento>> rolesMementos;

public Memento getMemento() {

return memento;

}

public void setMemento(Memento memento) {

this.memento = memento;

}

}

接下来使用demo,体会备忘录模式是怎么解决这个问题的吧

public static void main(String[] args) {

//创建游戏角色

GameRole gameRole = new GameRole();

gameRole.setVit(100);

gameRole.setDef(100);

System.out.println("和 boss 大战前的状态");

gameRole.display();

//创建备忘录把当前状态保存 caretaker

Caretaker caretaker = new Caretaker();

caretaker.setMemento(gameRole.createMemento());

System.out.println("和 boss 大战~~~");

gameRole.setDef(30);

gameRole.setVit(30);

gameRole.display();

System.out.println("大战后,使用备忘录对象恢复到站前");

gameRole.recoverGameRoleFromMemento(caretaker.getMemento());

System.out.println("恢复后的状态");

gameRole.display();

}

运行结果如下:

和 boss 大战前的状态

游戏角色当前的攻击力:100 防御力: 100

和 boss 大战~~~

游戏角色当前的攻击力:30 防御力: 30

大战后,使用备忘录对象恢复到站前

恢复后的状态

游戏角色当前的攻击力:100 防御力: 100

若多个游戏角色,可以采用集合去存储管理,对应搞得每个角色的状态也可以使用K:V键值对的方式存储不同时期备忘录

备忘录模式的注意事项和细节


给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态

实现了信息的封装,使得用户不需要关心状态的保存细节

如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存, 这个需要注意

适用的应用场景:1、后悔药。 2、打游戏时的存档。 3、Windows 里的 ctri + z。 4、IE 中的后退。 4、数据库的事务管理

为了节约内存,备忘录模式可以和原型模式配合使用

参考资料


尚硅谷:设计模式(韩顺平老师):备忘录模式

Refactoring.Guru:《深入设计模式》

java程序员设计模式

阅读 35发布于 今天 01:46

本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议


我所知道系列:设计模式

avatar

28640

心有多大,舞台就有多大

76 声望

7 粉丝

0 条评论

得票时间

avatar

28640

心有多大,舞台就有多大

76 声望

7 粉丝

宣传栏

前言介绍


接下里介绍的是Java 的设计模式之一:备忘录模式

我们还是以一个问题进行展开,引入备忘录模式

当前有一个游戏程序,玩家操控游戏角色,角色有攻击力和防御力,在大战 Boss 前需要保存自身的状态(攻击力和防御力),当大战 Boss 后可能会造成攻击力和防御力下降,这时需要恢复战前的状态

那么你会怎么解决这个问题?

一、传统方式解决问题

【Java】我所知道设计模式之备忘录模式

一个角色对应一个类的类,若游戏角色过多,则会有很多的类造成不利于开销与管理

传统的方式的问题分析

一个对象,就对应一个保存对象状态的对象,这样当我们游戏的对象很多时,不利于管理,开销也很大

传统的方式是简单地做备份,new 出另外一个对象出来,再把需要备份的数据放到这个新对象,但这就暴露了对象内部的细节

我们推荐使用:备忘录模式解决这个问题

二、什么是备忘录模式


备忘录模式(Memento Pattern)在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态

这样以后就可将该对象恢复到原先保存的状态

现实生活中的备忘录是用来记录某些要去做的事情,或者是记录已经达成的共同意见的事情,以防忘记了

在软件层面,备忘录模式有着相同的含义,备忘录对象主要用来记录一个对象的某种状态,或者某些数据,当要做回退时,可以从备忘录对象里获取原来的数据进行恢复操作

备忘录原理类图

【Java】我所知道设计模式之备忘录模式

originator :对象(需要保存状态的对象)
Memento :备忘录对象,负责保存好记录,即 Originator 内部状态
Caretaker:守护者对象,负责保存多个备忘录对象, 使用集合管理,提高效率

说明:如果希望保存多个 originator 对象的不同时间的状态,也可以,只需要要 HashMap <String, 集合>

三、使用备忘录解决问题

【Java】我所知道设计模式之备忘录模式

根据思路,我们先开始创建与原始对象游戏角色的备忘录

//备忘录Memento

class Memento {

//攻击力

private int vit;

//防御力

private int def;

public Memento(int vit, int def) {

super();

this.vit = vit;

this.def = def;

}

public int getVit() {return vit;}

public void setVit(int vit) {this.vit = vit;}

public int getDef() {return def;}

public void setDef(int def) {this.def = def; }

}

接着创建原始对象游戏角色,攻击力、防御力

class GameRole {

//攻击力

private int vit;

//防御力

private int def;

//创建 Memento ,即根据当前的状态得到 Memento

public Memento createMemento() {

return new Memento(vit, def);

}

//从备忘录对象,恢复 GameRole 的状态

public void recoverGameRoleFromMemento(Memento memento) {

this.vit = memento.getVit();

this.def = memento.getDef();

}

//显示当前游戏角色的状态

public void display() {

System.out.println("游戏角色当前的攻击力:" + this.vit + " 防御力: " + this.def);

}

public int getVit() {return vit;}

public void setVit(int vit) { this.vit = vit;}

public int getDef() { return def;}

public void setDef(int def) { this.def = def;}

}

接下来创建管理多个备忘录的守护者类

//守护者对象, 保存游戏角色的状态

class Caretaker {

//如果只保存一次状态

private Memento memento;

//对 GameRole 保存多次状态

private ArrayList<Memento> mementos;

//对多个游戏角色保存多个状态

private HashMap<String, ArrayList<Memento>> rolesMementos;

public Memento getMemento() {

return memento;

}

public void setMemento(Memento memento) {

this.memento = memento;

}

}

接下来使用demo,体会备忘录模式是怎么解决这个问题的吧

public static void main(String[] args) {

//创建游戏角色

GameRole gameRole = new GameRole();

gameRole.setVit(100);

gameRole.setDef(100);

System.out.println("和 boss 大战前的状态");

gameRole.display();

//创建备忘录把当前状态保存 caretaker

Caretaker caretaker = new Caretaker();

caretaker.setMemento(gameRole.createMemento());

System.out.println("和 boss 大战~~~");

gameRole.setDef(30);

gameRole.setVit(30);

gameRole.display();

System.out.println("大战后,使用备忘录对象恢复到站前");

gameRole.recoverGameRoleFromMemento(caretaker.getMemento());

System.out.println("恢复后的状态");

gameRole.display();

}

运行结果如下:

和 boss 大战前的状态

游戏角色当前的攻击力:100 防御力: 100

和 boss 大战~~~

游戏角色当前的攻击力:30 防御力: 30

大战后,使用备忘录对象恢复到站前

恢复后的状态

游戏角色当前的攻击力:100 防御力: 100

若多个游戏角色,可以采用集合去存储管理,对应搞得每个角色的状态也可以使用K:V键值对的方式存储不同时期备忘录

备忘录模式的注意事项和细节


给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态

实现了信息的封装,使得用户不需要关心状态的保存细节

如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存, 这个需要注意

适用的应用场景:1、后悔药。 2、打游戏时的存档。 3、Windows 里的 ctri + z。 4、IE 中的后退。 4、数据库的事务管理

为了节约内存,备忘录模式可以和原型模式配合使用

参考资料


尚硅谷:设计模式(韩顺平老师):备忘录模式

Refactoring.Guru:《深入设计模式》

以上是 【Java】我所知道设计模式之备忘录模式 的全部内容, 来源链接: utcz.com/a/111907.html

回到顶部