十、备忘录模式
1. 定义
- 又叫快照模式,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态, 以便以后当需要时能将该对象恢复到原先保存的状态。
2. 结构
- 发起人(Originator)角色:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据 的功能,实现其他业务功能,它可以访问备忘录里的所有信息。
- 备忘录(Memento)角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起 人。
- 管理者(Caretaker)角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备 忘录的内容进行访问与修改。
- 窄接口:管理者(Caretaker)对象(和其他发起人对象之外的任何对象)看到的是备忘录 的窄接口(narror Interface),这个窄接口只允许他把备忘录对象传给其他的对象。
- 宽接口:与管理者看到的窄接口相反,发起人对象可以看到一个宽接口(wide Interface),这个宽接口允许它读取所有的数据,以便根据这些数据恢复这个发起人对象 的内部状态。
3. 案例
- 恋爱值案例
- 两种模式:
白箱
:对任何对象都提供一个接口,宽接口- UML
-
黑箱
:-
UML
-
4. 代码
以下为白盒
- RoleState
/**
* 备忘录角色类
*/
public class RoleState {
private int loveValue;//恋爱值
private boolean isMiss;//想念吗
public RoleState(int loveValue, boolean isMiss) {
this.loveValue = loveValue;
this.isMiss = isMiss;
}
public int getLoveValue() {
return loveValue;
}
public void setLoveValue(int loveValue) {
this.loveValue = loveValue;
}
public boolean isMiss() {
return isMiss;
}
public void setMiss(boolean miss) {
isMiss = miss;
}
}
- RoleManager
/**
* 备忘录对象管理对象
*/
public class RoleManager {
//存放角色对象
private RoleState roleState;
public RoleState getRoleState() {
return roleState;
}
public void setRoleState(RoleState roleState) {
this.roleState = roleState;
}
}
- Jerry
/**
* 作者本人的类
*/
public class Jerry {
private int loveValue;//恋爱值
private boolean isMiss;//想念吗
//初始化内部状态
public void initState(){
this.loveValue = 100;
this.isMiss = false;
}
//分开后
public void separate(){
this.loveValue = 0;
this.isMiss = true;
}
//保存角色状态功能
public RoleState saveState(){
return new RoleState(loveValue,isMiss);
}
//恢复角色状态
public void recoverState(RoleState roleState){
//将备忘录对象中存储的状态赋值给当前对象的成员
this.loveValue = roleState.getLoveValue();
this.isMiss = roleState.isMiss();
}
//展示状态方法
public void show(){
System.out.println("恋爱值:"+loveValue);
System.out.println("想她吗:"+isMiss);
}
public int getLoveValue() {
return loveValue;
}
public void setLoveValue(int loveValue) {
this.loveValue = loveValue;
}
public boolean isMiss() {
return isMiss;
}
public void setMiss(boolean miss) {
isMiss = miss;
}
public Jerry(int loveValue, boolean isMiss) {
this.loveValue = loveValue;
this.isMiss = isMiss;
}
public Jerry() {
}
}
- 测试类
public class Client {
public static void main(String[] args) {
System.out.println("-----------恋爱前-----------");
//创建Jerry对象
Jerry jerry = new Jerry();
jerry.initState();
jerry.show();
//将Jerry当前的状态进行备份
//创建角色管理对象
RoleManager manager = new RoleManager();
manager.setRoleState(jerry.saveState());
System.out.println("-----------分手后-----------");
jerry.separate();
jerry.show();
System.out.println("-----------回到刚和Crj好时的状态-----------");
jerry.recoverState(manager.getRoleState());
jerry.show();
System.out.println("现实真残酷,真想在没有.....");
}
}
- 测试结果
-----------恋爱前-----------
恋爱值:100
想她吗:false
-----------分手后-----------
恋爱值:0
想她吗:true
-----------回到刚和Crj好时的状态-----------
恋爱值:100
想她吗:false
现实真残酷,真想在没有.....
黑盒
-
写到内部类
-
Jerry
/**
* 作者本人的类
*/
public class Jerry {
private int loveValue;//恋爱值
private boolean isMiss;//想念吗
public Jerry() {
}
//初始化内部状态
public void initState(){
this.loveValue = 100;
this.isMiss = false;
}
//分开后
public void separate(){
this.loveValue = 0;
this.isMiss = true;
}
//保存角色状态功能
public RoleState saveState(){
return new RoleState(loveValue,isMiss);
}
//恢复角色状态
public void recoverState(RoleState roleState){
//将备忘录对象中存储的状态赋值给当前对象的成员
this.loveValue = roleState.getLoveValue();
this.isMiss = roleState.isMiss();
}
//展示状态方法
public void show(){
System.out.println("恋爱值:"+loveValue);
System.out.println("想她吗:"+isMiss);
}
public int getLoveValue() {
return loveValue;
}
public void setLoveValue(int loveValue) {
this.loveValue = loveValue;
}
public boolean isMiss() {
return isMiss;
}
public void setMiss(boolean miss) {
isMiss = miss;
}
public Jerry(int loveValue, boolean isMiss) {
this.loveValue = loveValue;
this.isMiss = isMiss;
}
private class RoleState
{
private int loveValue;//恋爱值
private boolean isMiss;//想念吗
public RoleState(int loveValue, boolean isMiss) {
this.loveValue = loveValue;
this.isMiss = isMiss;
}
public int getLoveValue() {
return loveValue;
}
public void setLoveValue(int loveValue) {
this.loveValue = loveValue;
}
public boolean isMiss() {
return isMiss;
}
public void setMiss(boolean miss) {
isMiss = miss;
}
}
}
/**
* 备忘录接口,对外提供窄接口
*/
public interface Memento {
}
- 注意set不到了
public class RoleManager {
//声明备忘录接口类型变量
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
//set不到
// memento.set
}
}
5. 优缺点
-
优点
- 提供了一种可以恢复状态的机制。
- 实现了内部状态的封装
-
缺点
- 资源消耗大:保存的内部信息过多或频繁
6. 使用场景
- 需要恢复数据的场景
- 需要提供回滚操作的场景