DesignPattern - 备忘录模式【行为型】
# 一、备忘录模式介绍
备忘录模式(Memento Pattern)又叫做快照模式,属于行为模式。在不破坏封闭的前提下,捕获一个对象的内部状态,保存对象的某个状态,以便在适当的时候恢复对象。使用备忘录模式实现的方式需要保证被保存的对象状态不能被对象从外部访问
核心组成
- Originator 发起者:记录当前的内部状态,并负责创建和恢复备忘录数据,允许返回到先前状态所需的所有数据,可以根据需要决定 Memento 存储自己的哪些内部状态
- Memento 备忘录:负责存储 Originator 发起人对象的内部状态,在需要的时候提供发起人需要的内部状态(Memento 与 Originator 的属性类似)
- Caretaker 管理者:对备忘录进行管理、保存和提供备忘录,只能将备忘录传递给其他角色
应用场景
- 玩游戏的时候肯定有存档功能,下一次登录游戏时可以从上次退出的地方继续游戏
- 棋盘类游戏的悔棋、数据库事务回滚
- 需要记录一个对象的内部状态时,为了允许用户取消不确定或者错误的操作,能够恢复到原先的状态
- 提供一个可回滚的操作,如 ctrl+z、浏览器回退按钮
优点
- 给用户提供了一种可以恢复状态的机制
- 实现了信息的封装,使得用户不需要关心状态的保存细节
缺点
- 消耗更多的资源,而且每一次保存都会消耗一定的内存
# 二、备忘录模式代码实现
以类 "拳皇" 对打游戏为例,一个游戏角色拥有初始生命值和攻击力,随着每次出拳,生命值下降,同时攻击力上升,结合快照作弊器,每次生命值较低时,恢复到原来保存的状态。
创建 发起者(也就是游戏角色):
/**
* 发起者:一个游戏角色
*
* @author GitLqr
*/
public class RoleOriginator {
// 生命值,会减少
private int live = 100;
// 攻击力,会上涨
private int attack = 50;
public void display() {
System.out.println("生命值:" + live);
System.out.println("攻击力:" + attack);
}
/**
* 打架(每次攻击力上涨2点,生命值下降10点)
*/
public void fight() {
live -= 10;
attack += 2;
}
/**
* 保存快照,存储当前状态
*/
public RoleStateMemento saveState() {
return new RoleStateMemento(live, attack);
}
/**
* 恢复
*/
public void recoveryState(RoleStateMemento memento) {
this.live = memento.getLive();
this.attack = memento.getAttack();
}
}
创建 备忘录(快照):
/**
* 备忘录(快照):角色状态快照
*
* @author GitLqr
*/
public class RoleStateMemento {
// 生命值
private int live;
// 攻击力
private int attack;
public RoleStateMemento(int live, int attack) {
super();
this.live = live;
this.attack = attack;
}
public int getLive() {
return live;
}
public void setLive(int live) {
this.live = live;
}
public int getAttack() {
return attack;
}
public void setAttack(int attack) {
this.attack = attack;
}
}
创建 管理者:
/**
* 管理者:角色状态快照管理器
*
* @author GitLqr
*/
public class RoleStateCaretaker {
// 根据开发需要,可以使用集合来保存之前的快照信息
private RoleStateMemento memento;
public RoleStateMemento getMemento() {
return memento;
}
public void setMemento(RoleStateMemento memento) {
this.memento = memento;
}
}
使用:
public static void main(String[] args) {
RoleOriginator roleOriginator = new RoleOriginator();
roleOriginator.display();
System.out.println("保存当前的状态快照");
RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker();
roleStateCaretaker.setMemento(roleOriginator.saveState());
roleOriginator.fight();
roleOriginator.fight();
roleOriginator.fight();
roleOriginator.display();
System.out.println("恢复之前的状态快照");
roleOriginator.recoveryState(roleStateCaretaker.getMemento());
roleOriginator.display();
}
上次更新: 2024/11/24, 11:42:29
- 01
- Flutter - 子部件任意位置观察滚动数据11-24
- 02
- Flutter - 危!3.24版本苹果审核被拒!11-13
- 03
- Flutter - 轻松搞定炫酷视差(Parallax)效果09-21