16.命令模式
[实验任务一]:多次撤销和重复的命令模式
某系统需要提供一个命令集合(注:可以使用链表,栈等集合对象实现),用于存储一系列命令对象,并通过该命令集合实现多次undo()和redo()操作,可以使用加法运算来模拟实现。
类图
代码
java代码
package test16;
public abstract class AbstractCommand {
public abstract int execute(int value);
public abstract int undo();
public abstract int redo();
}
package test16;
public class Adder {
private int num = 0;
public int add(int value){
num += value;
return num;
}
}
package test16;
public class CalculatorForm {
private AbstractCommand command;
public void setCommand(AbstractCommand command){
this.command = command;
}
public void compute(int value){
int i = command.execute(value);
System.out.println("execute compute success,The result is "+i);
}
public void undo(){
int i = command.undo();
if(i!=-1) {
System.out.println("execute undo success,The result is " + i);
}
}
public void redo(){
int i = command.redo();
if(i!=-1){
System.out.println("execute redo success,The result is "+i);
}
}
}
package test16;
public class Client {
public static void main(String[] args) {
CalculatorForm form = new CalculatorForm();
AbstractCommand command;
command = new ConcreteCommand();
form.setCommand(command);
form.compute(10);
form.compute(3);
form.undo();
form.undo();
form.undo();
form.redo();
form.redo();
form.redo();
}
}
package test16;
import java.util.ArrayList;
import java.util.List;
public class ConcreteCommand extends AbstractCommand{
/**
* @apiNote This is my code
* @date 2022.10.20
*/
private Adder adder = new Adder();
private int value;
private List<Integer> undoValue = new ArrayList<>();
private List<Integer> redoValue = new ArrayList<>();
@Override
public int execute(int value) {
this.value = value;
//The addition goes to the undo queue, which means the operation can be undone
undoValue.add(value);
return adder.add(value);
}
@Override
public int undo() {
if (undoValue.size()>0){
int val = undoValue.get(undoValue.size()-1);
undoValue.remove(undoValue.size()-1);
//If added to the recovery group, recovery can be performed
redoValue.add(val);
return adder.add(-val);
}else {
System.out.println("It is't undo");
return -1;
}
}
@Override
public int redo() {
if(redoValue.size()>0){
int val = redoValue.get(redoValue.size()-1);
redoValue.remove(redoValue.size()-1);
undoValue.add(val);
return adder.add(val);
}else {
System.out.println("It is't redo");
return -1;
}
}
}
C++代码
#include <iostream>
#include <list>
using namespace std;
class AbstractCommand{
public:
virtual int execute(int value){};
virtual int undo(){};
virtual int redo(){};
};
class Adder{
private:
int num = 0;
public:
int add(int value) {
num += value;
return num;
}
};
class CalculatorForm{
private:
AbstractCommand* command;
public:
void setCommand(AbstractCommand* command){
this->command = command;
}
void compute(int value){
int i = command->execute(value);
cout<<"execute compute success,The result is ";
cout<<i<<endl;
}
void undo(){
int i = command->undo();
if(i!=-1) {
cout<<"execute undo success,The result is ";
cout<<i<<endl;
}
}
void redo(){
int i = command->redo();
if(i!=-1){
cout<<"execute redo success,The result is ";
cout<<i<<endl;
}
}
};
class ConcreteCommand: public AbstractCommand{
private:
Adder adder;
int value;
list<int> undoValue;
list<int> redoValue;
public:
int execute(int value) {
this->value = value;
//The addition goes to the undo queue, which means the operation can be undone
undoValue.push_back(value);
return adder.add(value);
}
int undo() {
if (undoValue.size()>0){
int val = undoValue.back();
undoValue.remove(undoValue.size()-1);
//If added to the recovery group, recovery can be performed
redoValue.push_back(val);
return adder.add(-val);
}else {
cout<<"It is't undo"<<endl;
return -1;
}
}
int redo() {
if(redoValue.size()>0){
int val = redoValue.back();
redoValue.remove(redoValue.size()-1);
undoValue.push_back(val);
return adder.add(val);
}else {
cout<<"It is't redo"<<endl;
return -1;
}
}
};
int main(){
CalculatorForm form;
ConcreteCommand *command = new ConcreteCommand;
form.setCommand(command);
form.compute(10);
form.compute(3);
form.undo();
form.undo();
form.undo();
form.redo();
form.redo();
form.redo();
}