命令模式-实现undo和redo
这次实验主要是实现多次redo和undo,即程序的撤回和恢复,这里只实现加法的撤回和恢复。
程序的撤回和恢复就是由所使用的软件来记录操作步骤,可以将数据恢复到某个操作状态。
撤回这个指令很常见,Windows系统常用的快捷键ctrl+z就可以实现撤回的效果
恢复目前只在word等文档编辑软件见到。

首先说一下命令模式的结构(参考该类图,使用starUML制作):

Adder类是加法的计算和返回计算后的结果, AbstrCommand是抽象类,定义三个抽象方法,AddCommand类继承AbstrCommand类,对AbstrCommand进行扩展,
这样就可以灵活的改变命令的内容,和添加新命令。CalculatorForm类是调用AbstrCommand的方法,实现操作,并对操作的结果进行处理。通过该结构可以完成撤回和
回复的实现。
该结构又优点,这样设计降低了系统的耦合度,也方便加入新命令。
接下来说一下算法实现的原理:
首先要想撤回和恢复的实现,需要有两个栈(链表也可以),一个栈用来存储操作的每个步骤的结果,命名为撤回栈,另一个表用来
存储撤回栈弹出的数据,命名为恢复栈。在进行加法操作的时候需要在将最新的结果压入撤回栈(保存最新操作),恢复栈清空(每次进行加法操作,
需要清空撤回栈弹出的数据),在撤回栈的时候需要将撤回栈的栈顶弹出,并将其压入恢复栈(保存),在恢复时需要将恢复栈的栈顶弹出,并将其
压入撤回栈,这样就完成了基本的实现,不要忘了再加上栈的空的判断。
栈的使用:stack<Object> stack = new Stack<Object>(); 定义 (说明类型)
Object j=stack.peek(); 返回栈顶元素的值
Object j=stack.pop(); 弹出栈顶元素的值,j是弹出的值
Object j=stack.push(Object element); 将值压入栈
源代码:
//实现加法的计算和返回计算的值
public class Adder {
private int num =0;
public int add(int value) {
num+=value;
return num;
}
}
Adder类
//抽象命令类
public abstract class AbstractCommand {
public abstract int execute(int value);
public abstract int undo();
public abstract int redo();
}
AbstractCommand 类
//加法命令类
import java.util.Stack;
public class AddCommand extends AbstractCommand {
private Adder adder = new Adder();
private Stack<Integer> unStack = new Stack<Integer>();// 返回栈,用来记录所做的每一步操作,用于撤回
private Stack<Integer> reStack = new Stack<Integer>();// 重复栈,用来存储返回栈弹出的数据,由于重复
/**
* 撤回
*/
public int undo() {
int i=0;
if (unStack.isEmpty()) {
i=-1;
}else{
Integer pop = unStack.pop();
reStack.push(pop);
if(!unStack.isEmpty()){//判断弹出数据后是否为空,如果为空,说明已撤回到最原始状态
i=unStack.peek();
}
}
return i;
}
/**
* 恢复
*/
public int redo() {
int i=0;
if (reStack.isEmpty()) {
i=-1;
}else{//撤回时只要可以可以撤回,则返回栈一定有数据
Integer pop = reStack.pop();
unStack.push(pop);
i=pop;
}
return i;
}
/**
* 执行计算,并进行栈的更新
*/
public int execute(int value) {
int v = 0;
if (unStack.isEmpty()) {// 说明还没有数据
v = adder.add(value);
unStack.push(v);
} else {// 需要更新两个栈中的内容,并计算结果,其中返回栈应该更新,重复栈应该清空
v = adder.add(value);
unStack.push(v);
if (!reStack.isEmpty()) {
for (int i = 0; i < reStack.size(); i++) {
reStack.pop();
}
}
}
return v;
}
}
AddCommand类
public class CalculatorForm {
private AbstractCommand command;
public void setCommand(AbstractCommand command) {
this.command =command;
}
/**
* 执行运算
* @param value
*/
public void compute(int value) {
command.execute(value);
}
/**
* 撤回
*/
public void undo() {
int i = command.undo();
if(i==-1){
System.out.println("缓存中已不存在数据");
}else{
System.out.println("执行成功,运算结果是:"+i);
}
}
/**
* 恢复
*/
public void redo() {
int i = command.redo();
if(i==-1){
System.out.println("已恢复至最新数据");
}
else{
System.out.println("执行成功,运算结果是:"+i);
}
}
}
CalculatorForm(引用命令)类
//测试结果
public class client {
public static void main(String[] args) {
CalculatorForm form = new CalculatorForm();
AddCommand command = new AddCommand();
form.setCommand(command);
//计算
System.out.println("------计算过程-----");
form.compute(1);
form.compute(2);
form.compute(3);
form.compute(4);
//多次撤回
System.out.println("------撤回过程-----");
form.undo();
form.undo();
form.undo();
form.undo();
form.undo();
//多次恢复
System.out.println("------恢复过程-----");
form.redo();
form.redo();
form.redo();
form.redo();
form.redo();
}
}
client 类
实验总结:
通过本次试验,对命令模式有了基本了解,命令模式很容易实现undo和redo,在本次试验我使用了stack栈用来实现多次的撤回和恢复,透彻理解使用两个栈,用来对数据
进行恢复的原理,就可以很快的解决该问题。
命令模式-实现undo和redo的更多相关文章
- 从Undo,Redo谈命令模式
一般的应用软件中,通常会提供Redo和Undo的操作,比如Paint.NET中的动作面板,Word中的撤销重做,一般我们按Ctrl-Z即可回退到上次操作. 要实现上面的这一功能,最直观的想法就是,我们 ...
- 设计模式 - 命令模式(command pattern) 撤销(undo) 具体解释
命令模式(command pattern) 撤销(undo) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.cs ...
- [Head First设计模式]餐馆中的设计模式——命令模式
系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...
- c#设计模式-命令模式
一. 命令(Command)模式 命令(Command)模式属于对象的行为模式[GOF95].命令模式又称为行动(Action)模式或交易(Transaction)模式.命令模式把一个请求或者操作封装 ...
- 15.命令模式(Command Pattern)
using System; namespace ConsoleApplication8 { class Program { /// <summary> /// 在软件系统中,“行为请求者” ...
- 深入浅出设计模式——命令模式(Command Pattern)
模式动机 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请 ...
- C#设计模式(15)——命令模式(Command Pattern)
一.前言 之前一直在忙于工作上的事情,关于设计模式系列一直没更新,最近项目中发现,对于设计模式的了解是必不可少的,当然对于设计模式的应用那更是重要,可以说是否懂得应用设计模式在项目中是衡量一个程序员的 ...
- 大熊君说说JS与设计模式之------命令模式Command
一,总体概要 1,笔者浅谈 日常生活中,我们在看电视的时候,通过遥控器选择我们喜欢的频道时,此时我们就是客户端的角色,遥控器的按钮相当于客户请求,而具体执行的对象就是命令对象, 命令模式把一个请求或者 ...
- 设计模式:命令模式(Command)
定 义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排列或者记录请求日志,以及支持可撤销的操作. 结构图: Command类: abstract class Comma ...
随机推荐
- HUE配置文件hue.ini 的yarn_clusters模块详解(图文详解)(分HA集群和非HA集群)
不多说,直接上干货! 我的集群机器情况是 bigdatamaster(192.168.80.10).bigdataslave1(192.168.80.11)和bigdataslave2(192.168 ...
- Python -- 数据库连接
1.连接MySQL(x64系统装不上x32版本) MySQL现在都不支持Python3 import MySQLdb con = MySQLdb.connect(host='127.0.0.1', u ...
- C/C++练习题(三)
1.对下面两个文件编译后,运行会输出什么? // 第一个文件a.c #include <stdio.h> extern char p[]; extern void f(); int mai ...
- WPF将TextBox的边框设为圆角的
将TextBox的边框设为圆角的,因为TextBox默认的样式中边框就是由Border类型来实现的, 所以只需要真的当前的TextBox的Border修改属性即可,为了不影响界面中别的Border的样 ...
- kendo UI 入门
Kendo UI 是一套前端开发宽假,意为日本的“剑道” 首先到官方网站下载最新的30天试用版,地址为:http://www.telerik.com/download/kendo-ui 需要简单注册一 ...
- HTML引入CSS样式的四种方法
在HTML中引入CSS的方法主要有四种,它们分别是行内式.内嵌式.链接式和导入式. 1.行内式 行内式是在标记的style属性中设定CSS样式.这种方式没有体现出CSS的优势,不推荐 ...
- C#中Cookie,Session,Application的用法与区别?
1.Application 储存在服务端,没有时间限制,服务器关闭即销毁(前提是自己没写销毁方法) 2.Session 储存在服务端,客户端(浏览器)关闭即销毁(若长时间不使用 且 浏览器未关闭的情况 ...
- webpack 项目实践
1,必要的环境 node 环境 下载地址(http://nodejs.cn/) npm 貌似 下载地址(https://www.npmjs.com/)不过,貌似 Node 安装可自带 npm. 2, ...
- UIWebView 展示GIF/image
代码: [web loadData:self.gifDataArr[index] MIMEType:@"image/gif" textEncodingName:@"&qu ...
- Exception的情况——java基础1
除数为0等ArithmeticException,是RuntimException的子类.而运行时异常将由运行时系统自动抛出,不需要使用throw语句.Java编译器允许忽略运行时异常,一个方法可以既 ...