设计模式之备忘录模式(下)

3)实现多次撤销
1.结构图

对负责人类MementoCaretaker进行了修改,在其中定义了一个ArrayList类型的集合对象来存储多个备忘录。

2.代码实现
复制代码
import java.util.*;
 
public class MementoCaretaker {
  //定义一个集合来存储多个备忘录
	private ArrayList mementolist = new ArrayList();
 
	public ChessmanMemento getMemento(int i) {
		return (ChessmanMemento)mementolist.get(i);
	}
 
	public void setMemento(ChessmanMemento memento) {
		mementolist.add(memento);
	}
}

客户端类

复制代码
public class Client {
	private static int index = -1; //定义一个索引来记录当前状态所在位置
	private static MementoCaretaker mc = new MementoCaretaker();
 
	public static void main(String args[]) {
		Chessman chess = new Chessman("车",1,1);
		play(chess);		
		
		chess.setY(4);
		play(chess);
		
		chess.setX(5);
		play(chess);	
		
		undo(chess,index);
		undo(chess,index);	
		redo(chess,index);
		redo(chess,index);
	}
	
  //下棋
	public static void play(Chessman chess) {
	  //保存备忘录
		mc.setMemento(chess.save()); 
		index++; 
		System.out.println("棋子" + chess.getLabel() + "当前位置为:" + "第" + chess.getX() + "行" + "第" + chess.getY() + "列。");
	}
 
	//悔棋
	public static void undo(Chessman chess,int i) {
		System.out.println("******悔棋******");
		index--; 
		chess.restore(mc.getMemento(i-1)); //撤销到上一个备忘录
		System.out.println("棋子" + chess.getLabel() + "当前位置为:" + "第" + chess.getX() + "行" + "第" + chess.getY() + "列。");
	}
 
	//撤销悔棋
	public static void redo(Chessman chess,int i) {
		System.out.println("******撤销悔棋******");	
		index ++; 
		chess.restore(mc.getMemento(i+1)); //恢复到下一个备忘录
		System.out.println("棋子" + chess.getLabel() + "当前位置为:" + "第" + chess.getX() + "行" + "第" + chess.getY() + "列。");
	}
} 
3.注意

本实例只能实现最简单的Undo和Redo操作,并未考虑对象状态在操作过程中出现分支的情况。

如果在撤销到某个历史状态之后,用户再修改对象状态,此后执行Undo操作时可能会发生对象状态错误,在实际开发中,可以使用链表或者堆栈来处理有分支的对象状态改变。

4)总结

备忘录是一个很特殊的对象,只有原发器对它拥有控制的权力,负责人只负责管理,而其他类无法访问到备忘录。

1.优点
  • 它提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤。

  • 备忘录保存了原发器的状态,采用列表、堆栈等集合来存储备忘录对象可以实现多次撤销操作。

2.缺点

资源消耗过大,如果需要保存的原发器类的成员变量太多,就不可避免需要占用大量的存储空间,每保存一次对象的状态都需要消耗一定的系统资源。

3.适用场景
  • 保存一个对象在某一个时刻的全部状态或部分状态,以后需要时能够恢复到先前的状态,实现撤销操作。

  • 防止外界对象破坏一个对象历史状态的封装性,避免将对象历史状态的实现细节暴露给外界对象。

相关推荐
饼干哥哥1 天前
字节Seedance2.5终于上线,这次在收割谁?
人工智能·设计模式·前端框架
董员外1 天前
RAG 系统进化论(六):GraphRAG(基于知识图谱的 RAG),从相似文本走向实体关系
人工智能·后端·设计模式
鬼鬼鬼1 天前
从 Prompt 到 Harness:企业级 Agent 工程的完整演进之路
设计模式·架构·ai编程
啦啦啦啦啦zzzz1 天前
设计模式:原型模式
c++·设计模式·原型模式
董员外1 天前
RAG 系统进化论(五):Corrective RAG 与 Self-RAG,让系统发现并纠正错误
人工智能·后端·设计模式
workflower2 天前
高质量数据集的类型
人工智能·机器学习·设计模式·自然语言处理·机器人
啦啦啦啦啦zzzz2 天前
工具:动态类工厂和用配置文件存储属性
c++·设计模式·工具·动态工厂
Nontee2 天前
设计模式:模板方法与策略,从“每个字都认识“到能说清它们在干嘛
java·数据库·设计模式
choumin2 天前
行为型模式——模板方法模式
c++·设计模式·模板方法模式·行为型模式
啦啦啦啦啦zzzz2 天前
设计模式:建造者模式
c++·设计模式·建造者模式