备忘录(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样我们就可以将该对象复原到原先保存的状态。
很多时候我们需要记录一个对象的内部状态,允许用户取消不确定或者错误的操作,恢复到他原来的状态,备忘录模式就提供了这样一种可以恢复状态的机制,可以使我们比较方便的回到某一个历史状态,比如游戏的存档、数据库的事务等
Originator(发起人):负责创建一个备忘录 Memento,用来记录当前时刻它的内部状态,并可以使用备忘录恢复内部状态。Originator 可以根据需要决定 Memento 存储 Originator 的哪些内部状态
import lombok.Data;
/**
* 发起人
*/
@Data
public class Originator {
// 需要保存的属性
private String blood;
private String status;
public Originator() {
}
public Originator(String blood, String status) {
this.blood = blood;
this.status = status;
}
/**
* 创建备忘录,将需要爆粗你的信息保存
*
* @return 备忘录对象
*/
public Memento createMemento() {
return new Memento(blood, status);
}
/**
* 恢复备忘录,将 Memento 导入并将数据恢复
*/
public void setMemento(Memento memento) {
status = memento.getStatus();
blood = memento.getBlood();
}
/**
* 显示数据
*/
public void show() {
System.out.println("status = " + status + ",blood = " + blood);
}
}
Memento(备忘录):负责存储 Originator 对象的内部状态
import lombok.Data;
/**
* 备忘录
*/
@Data
public class Memento {
private String blood;
private String status;
public Memento() {
}
public Memento(String blood, String status) {
this.blood = blood;
this.status = status;
}
}
Caretaker(管理者):负责保存好备忘录 Memento,不能对备忘录内的内容进行操作或者检查
import lombok.Data;
/**
* 管理者
*/
@Data
public class Caretaker {
private Memento memento;
}
调用方代码
public class MementoClient {
public static void main(String[] args) {
// Originator 初始状态,血量 100,状态 on
Originator originator = new Originator();
originator.setStatus("on");
originator.setBlood("100");
originator.show();
// 保存状态到管理者
Caretaker caretaker = new Caretaker();
Memento memento = originator.createMemento();
caretaker.setMemento(memento);
// 改变属性,状态 off,血量 10
originator.setStatus("off");
originator.setBlood("10");
originator.show();
// 恢复原来的状态
originator.setMemento(caretaker.getMemento());
originator.show();
}
}
// status = on,blood = 100
// status = off,blood = 10
// status = on,blood = 100
备忘录模式将保存的细节封装到了 Memento 中,需要更改保存的细节的话不会影响到客户端
一个游戏角色有生命力、攻击力、防御力等属性,可以中途退出并存档,重新进入后恢复角色状态
Role:游戏角色类
import lombok.Data;
@Data
public class Role {
/**
* 攻击
*/
private Integer attack;
/**
* 血量
*/
private Integer blood;
/**
* 防御
*/
private Integer defense;
private void init() {
this.defense = 100;
this.blood = 100;
this.attack = 5;
}
/**
* 角色状态查看
*/
public void show() {
System.out.println("血量:" + blood + " 攻击:" + attack + " 防御:" + defense);
}
/**
* 保存角色状态
*
* @return 角色状态备忘录
*/
public RoleMemento save() {
return RoleMemento.builder()
.blood(blood)
.attack(attack)
.defense(defense)
.build();
}
/**
* 恢复角色状态
*/
public void Recover(RoleMemento roleMemento) {
this.defense = roleMemento.getDefense();
this.blood = roleMemento.getBlood();
this.attack = roleMemento.getAttack();
}
}
RoleMemento:角色备忘录(角色状态存储)
import lombok.Builder;
import lombok.Data;
/**
* 角色状态存储
*/
@Data
@Builder
public class RoleMemento {
/**
* 攻击
*/
private Integer attack;
/**
* 血量
*/
private Integer blood;
/**
* 防御
*/
private Integer defense;
}
RoleCaretaker:角色状态管理
import lombok.Data;
/**
* 角色管理者
*/
@Data
public class RoleCaretaker {
private RoleMemento roleMemento;
}
调用代码:
public class GameClient {
public static void main(String[] args) {
Role zhangSan = new Role();
// 角色初始化
zhangSan.init();
zhangSan.show();
// 保存进度
RoleCaretaker roleCaretaker = new RoleCaretaker();
// 具体保存的数据没有透传出来
roleCaretaker.setRoleMemento(zhangSan.save());
// 角色战斗,数据下降
zhangSan.fight();
zhangSan.show();
// 恢复状态
zhangSan.recover(roleCaretaker.getRoleMemento());
zhangSan.show();
}
}
// 血量:100 攻击:5 防御:100
// 血量:20 攻击:5 防御:30
// 血量:100 攻击:5 防御:100