某系统需要提供一个命令集合(注:可以使用链表,栈等集合对象实现),用于存储一系列命令对象,并通过该命令集合实现多次undo()和redo()操作,可以使用加法运算来模拟实现。\

类图:

Java代码:

package Lab16;
import java.util.Stack; public abstract class AbstractCommand {
public abstract int execute(int value);
public abstract int undo();
public abstract int redo();
} 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;
}
} public class Adder {
private int num =0;
public int add(int value) {
num+=value;
return num;
}
} 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);
}
}
} 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();
}
}

C++代码:

#include<iostream>
#include<stack>
using namespace std;
int num=0;
class AbstractCommand {
public:
virtual int execute(int value)=0;
virtual int undo()=0;
virtual int redo()=0;
};
class Adder { public:
int add(int value) {
num+=value;
return num;
}
};
class AddCommand :public AbstractCommand {
private:
Adder *adder;
stack<int> unStack;
stack<int> reStack;
public:
int undo() {
//adder= new Adder();
int i=0;
if (unStack.empty()) {
i=-1;
}else{
int pop = unStack.top();
reStack.push(pop);
unStack.pop();
if(!unStack.empty()){//判断弹出数据后是否为空,如果为空,说明已撤回到最原始状态
i=unStack.top();
}
} return i;
}
int redo() {
//adder= new Adder();
int i=0;
if (reStack.empty()) {
i=-1;
}else{//撤回时只要可以可以撤回,则返回栈一定有数据
// reStack.pop(); int pop = reStack.top();
reStack.pop();
unStack.push(pop);
i=pop; }
return i;
}
int execute(int value) { int v = 0;
if (unStack.empty()) {// 说明还没有数据
v = adder->add(value);
unStack.push(v);
} else {// 需要更新两个栈中的内容,并计算结果,其中返回栈应该更新,重复栈应该清空
v = adder->add(value);
unStack.push(v);
if (!reStack.empty()) {
for (int i = 0; i < reStack.size(); i++) {
// reStack.top();
//reStack.pop();
}
}
}
return v;
}
};
class CalculatorForm {
private:
AbstractCommand *command;
public:
void setCommand(AbstractCommand *command) {
this->command =command;
}
void compute(int value) {
command->execute(value);
}
void undo() {
int i = command->undo();
if(i==-1){
cout<<"缓存中已不存在数据"<<endl;
}else{
cout<<"执行成功,运算结果是:"<<i<<endl;
}
}
void redo() {
int i = command->redo();
if(i==-1){
cout<<"已恢复至最新数据"<<endl;
}
else{
cout<<"执行成功,运算结果是:"<<i<<endl;
}
}
};
int main(){
CalculatorForm *form = new CalculatorForm();
AddCommand *command = new AddCommand();
form->setCommand(command);
//计算
cout<<"------计算过程------"<<endl;
form->compute(1);
form->compute(2);
form->compute(3);
form->compute(4);
//多次撤回
cout<<"------撤回过程------"<<endl;
form->undo();
form->undo();
form->undo();
form->undo();
form->undo();
//多次恢复
cout<<"------恢复过程------"<<endl;
form->redo();
form->redo();
form->redo();
form->redo();
form->redo();
return 0;
}

运行截图:

Java/C++实现命令模式---多次撤销和撤回的更多相关文章

  1. 折腾Java设计模式之命令模式

    博客原文地址 折腾Java设计模式之命令模式 命令模式 wiki上的描述 Encapsulate a request as an object, thereby allowing for the pa ...

  2. 设计模式 - 命令模式(command pattern) 撤销(undo) 具体解释

    命令模式(command pattern) 撤销(undo) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考命令模式: http://blog.cs ...

  3. Java设计模式 之 命令模式

    1      从属模式分类 行为性模式 2      命令模式意图 命令模式可将动作的请求者和动作的执行者对象中解耦. 该模式将一个行为操作发起者的请求封装到对象中,该请求由另外一个对象执行. 将动作 ...

  4. JAVA设计模式之 命令模式【Command Pattern】

    一.概述 命令模式能够将请求发送者和接收者全然解耦.发送者与接收者之间没有直接引用关系,发送请求的对象仅仅须要知道怎样发送请求,而不必知道怎样完毕请求.核心在于引入了命令类,通过命令类来减少发送者和接 ...

  5. java设计模式之命令模式以及在java中作用

    命令模式属于对象的行为模式.命令模式又称为行动(Action)模式或交易(Transaction)模式. 命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化,对请 ...

  6. 14.java设计模式之命令模式

    基本需求: 一套智能家电,有照明灯.风扇.冰箱.洗衣机,我们只要在手机上安装app就可以控制对这些家电工作 这些智能家电来自不同的厂家,我们不想针对每一种家电都安装一个App分别控制,我们希望只要一个 ...

  7. 玉帝传美猴王上天,大闹天宫之Java设计模式:命令模式

    目录 示例 改进代码 命令模式 定义 意图 主要解决问题 何时使用 优缺点 玉帝传美猴王上天 命令模式和策略模式的区别 示例 系统需要设计一个命令行界面,用户可输入命令来执行某项功能,系统的功能会不断 ...

  8. java设计模式之命令模式

    学校中.生活中.社会中总是会存在一定的阶层,虽然我们很多人都不可认可阶层的存在.命令这一词也就在阶层中诞生.家长命令孩子,老师命令学生,领导命令小娄娄.这些都在我们的生活存在的东西,相信这一个模式学习 ...

  9. Java设计模式菜鸟系列(七)命令模式建模与实现

    转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/39804057 命令模式(Command):将"请求"(命令/口令)封装 ...

随机推荐

  1. HarmonyOS UI组件在线预览,程序员直呼“不要太方便~”

    一.介绍 以往大家如果想查看组件的使用效果,需要打开DevEco Studio构建工程.现在为了便于大家高效开发,文档上线了JS UI组件在线预览功能,无需本地构建工程,在线即可修改组件样式等参数.一 ...

  2. 图解|从根上彻底理解MySQL的索引

    这是图解MySQL的第4篇文章,这篇文章会让你 明白什么是索引,彻底理解B+树和索引的关系: 彻底理解主键索引.普通索引.联合索引: 了解什么是HASH索引,InnoDB和MyISAM索引的不同实现方 ...

  3. 为什么我的MySQL会“抖”一下?

    不知道你有没有遇到过这样的场景,一条 SQL 语句,正常执行的时候特别快,但是有时也不知道怎么回事,它就会变得特别慢,并且这样的场景很难复现,它不只随机,而且持续时间还很短. 1)InnoDB 在处理 ...

  4. linux中文件颜色,蓝色,白色等各自代表的含义

    linux中文件颜色,蓝色,白色等各自代表的含义 绿色文件---------- 可执行文件,可执行的程序 红色文件-----------压缩文件或者包文件 蓝色文件----------目录 白色文件- ...

  5. JavaSE 千寻简学习笔记

    JavaSE 千寻简学习笔记 简介 TIOBE:编程语言排行榜 官网:https://hellogithub.com/report/tiobe/ 如何高效的学习Java 多写(代码)多写(笔记)多写( ...

  6. jdbc action 接口示例

    package com.gylhaut.action; import java.sql.SQLException;import java.util.ArrayList;import java.util ...

  7. [SPDK/NVMe存储技术分析]009 - Introduction to RDMA Send | RDMA Send操作概论

    来源: https://zcopy.wordpress.com/ 说明: 本文不是对原文的逐字逐句翻译,而是摘取核心部分以介绍RDMA Send操作(后面凡是提到RDMA send, 都对应于IBA里 ...

  8. CodeUp Problem D: More is better

    根据题目意思,输入的每一对A.B都是直接朋友,并且最后只会得到一个集合,该集合就是Mr Wang选择的男孩. 因此很容易写出代码,甚至不需要自己构建一个并查集,只需要使用C++的set模板,每次读入一 ...

  9. 从查询重写角度理解elasticsearch的高亮原理

    一.高亮的一些问题 elasticsearch提供了三种高亮方式,前面我们已经简单的了解了elasticsearch的高亮原理; 高亮处理跟实际使用查询类型有十分紧密的关系,其中主要的一点就是muti ...

  10. Linux 的目录结构是怎样的?

    这个问题,一般不会问.更多是实际使用时,需要知道.Linux 文件系统的结构层次鲜明,就像一棵倒立的树,最顶层是其根目录:Linux的目录结构常见目录说明: /bin:存放二进制可执行文件(ls,ca ...