命令模式-实现多次撤销与恢复

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

本次实验使用链表实现栈进而实现undo()redo()操作

 

 LinkStack

/**
 * 链表实现栈
 *
 * @param <T>
 */
class Stack<T> {
    //定义链表
    class Node<T> {
        private T t;
        private Node next;
    }
 
    private Node<T> head;
 
    //构造函数初始化头指针
    Stack() {
        head = null;
    }
 
    //入栈
    public void push(T t) {
        if (t == null) {
            throw new NullPointerException("参数不能为空");
        }
        if (head == null) {
            head = new Node<T>();
            head.t = t;
            head.next = null;
        } else {
            Node<T> temp = head;
            head = new Node<>();
            head.t = t;
            head.next = temp;
        }
    }
 
    //出栈
    public T pop() {
        T t = head.t;
        head = head.next;
        return t;
    }
 
    //栈顶元素
    public T peek() {
        T t = head.t;
        return t;
    }
 
    //栈空
    public boolean isEmpty() {
        if (head == null)
            return true;
        else
            return false;
    }
}
 public class LinkStack {
    public static void main(String[] args) {
        Stack stack = new Stack();
        System.out.println(stack.isEmpty());
        stack.push("Java");
        stack.push("is");
        stack.push("beautiful");
        System.out.println(stack.peek());
        System.out.println(stack.peek());
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack.isEmpty());
        System.out.println(stack.pop());
        System.out.println(stack.isEmpty());
    }
}

Client

abstract class AbstractCommand
{
    public abstract int execute(int value);
    public abstract int undo();
    public abstract int redo();
}

class ConcreteCommand extends AbstractCommand
{
    private Stack ustack=new Stack();
    private Stack rstack=new Stack();
    private Adder adder = new Adder();
    private int value;
        
    public int execute(int value)
    {
        this.value=value;
        
        ustack.push(value);
        return adder.add(value);
    }
    
    public int undo()
    {   
        if(ustack.isEmpty()==false) {
        Object a=ustack.pop();
        int s=Integer.parseInt(a.toString());
        //System.out.println(s);
        rstack.push(a);
        return adder.add(-s);
        }
        return 246810;  //标志代码,判断是否为空,最好用string
    }
    public int redo() {
        //rstack.pop();
        if(rstack.isEmpty()==false) {
        Object a=rstack.pop();
        int s=Integer.parseInt(a.toString());
        ustack.push(a);
        return adder.add(s);
        }
        return 13579;     //标志代码,判断是否为空,最好用string
        
    }
}

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("执行运算,运算结果为:" + i);
    }
    
    public void undo()
    {
        int i = command.undo();
        if(i==246810) {
            System.out.println("撤销已经结束");
        }
        else{
        System.out.println("执行撤销,运算结果为:" + i);
        }
    }
    public void redo()
    {   int i = command.redo();
        if(i==13579) {
            System.out.println("恢复已结束");
            return;
        }else
        { 
        System.out.println("执行恢复,运算结果为:" + i);
        }
    }
}

class Adder
{
    private int num=0;
    
    public int add(int value)
    {
        num+=value;
        return num;
    }
}

class Client
{
    public static void main(String args[])
    {
        CalculatorForm form = new CalculatorForm();
        ConcreteCommand command = new ConcreteCommand();
        form.setCommand(command);
        
        form.compute(10);//10+0=10  push 10
        form.compute(5);//10+5=15   push 5
        form.compute(10);//15+10=25  push 10
        form.undo();
        form.undo();
        form.undo();
        form.redo();
        form.redo();
        form.undo();
        form.redo();
        form.redo();
        form.redo();
        form.redo();
    }
}

 

 c++代码的实现

#include<iostream>
#include<string>
#include <stack>
using namespace std;
class AbstractCommand
{
public: virtual int execute(int value)=0;
        virtual int undo()=0;
        virtual int redo()=0;
};

class Adder
{
private: int num = 0;

public: int add(int value)
{
    num += value;
    return num;
}
};
class ConcreteCommand:public AbstractCommand
{
private: stack<int> ustack;
         stack<int> rstack;
         int value;
         Adder *adder = new Adder();


public: int execute(int value)
    {
        this->value = value;

        ustack.push(value);
        return adder->add(value);
    }

       int undo()
    {
        if (ustack.empty() == false) {
            int a = ustack.top();
            ustack.pop();
            //System.out.println(s);
            rstack.push(a);
            return adder->add(-a);
        }
        return 246810;  //标志代码,判断是否为空,最好用string
    }
      int redo() {
        //rstack.pop();
        if (rstack.empty() == false) {
            int a = rstack.top();
            rstack.pop();
            ustack.push(a);
            return adder->add(a);
        }
        return 13579;     //标志代码,判断是否为空,最好用string

    }
};

class CalculatorForm
{
private: AbstractCommand *command;

public: void setCommand(AbstractCommand *command)
    {
        this->command = command;
    }

       void compute(int value)
    {
        int i = command->execute(value);
        cout<<"执行运算,运算结果为:" <<i<<endl;
    }

     void undo()
    {
        int i = command->undo();
        if (i == 246810) {
            cout<<"撤销已经结束"<<endl;
        }
        else{
            cout<<"执行撤销,运算结果为:" <<i<<endl;
        }
    }
       void redo()
    {
        int i = command->redo();
        if (i == 13579) {
            cout<<"恢复已结束"<<endl;
            return;
        }
        else
        {
            cout<<"执行恢复,运算结果为:" <<i<<endl;
        }
    }
};


int main(){
        CalculatorForm *form = new CalculatorForm();
        ConcreteCommand *command = new ConcreteCommand();
        form->setCommand(command);

        form->compute(10);//10+0=10  push 10
        form->compute(5);//10+5=15   push 5
        form->compute(10);//15+10=25  push 10
        form->undo();
        form->undo();
        form->undo();
        form->redo();
        form->redo();
        form->undo();
        form->redo();
        form->redo();
        form->redo();
        form->redo();

}

 

posted @ 2021-11-03 09:01  好吗,好  阅读(407)  评论(0)    收藏  举报