21xrx.com
2025-06-21 14:38:31 Saturday
文章检索 我的文章 写文章
Java实现撤销上一步操作
2023-06-12 05:05:10 深夜i     14     0
Java 撤销 备忘录模式 命令模式

在编程中,有时候我们需要撤销上一步操作,以便更好地处理我们的数据。Java中提供了一些机制来实现撤销操作。下面我们将介绍几种实现方式。

1. 利用栈实现撤销

我们可以使用Java自带的栈数据结构来记录我们的撤销历史,每当我们进行一个操作时,都将该操作的相关信息压入栈中。当我们需要撤销时,我们只需要弹出栈顶元素并执行对应的撤销操作即可。下面是一个示例代码:

import java.util.Stack;
public class UndoStack {
  private Stack
  undoStack;
 
  public UndoStack() {
    undoStack = new Stack<>();
  }
  public void performAction(Action action) {
    action.doAction();
    undoStack.push(action);
  }
  public void undo() {
    if (!undoStack.empty()) {
      Action action = undoStack.pop();
      action.undoAction();
    }
  }
}
interface Action {
  void doAction();
  void undoAction();
}

上述代码中,我们定义了一个UndoStack类,用于记录我们的操作历史。当我们进行一个操作时,调用performAction方法并将操作的相关信息传入。这里我们还定义了一个Action接口,用于表示一个操作及其撤销。当我们需要撤销时,调用undo方法即可弹出栈顶元素,并调用其undoAction方法撤销上一步操作。

2. 利用备忘录模式实现撤销

我们还可以利用备忘录模式来实现撤销操作。备忘录模式是一种行为型模式,用于在不破坏封装性的前提下保存一个对象的状态。我们可以在每次操作之前保存对象的状态,并将其保存在备忘录中。当需要撤销时,我们只需要回到上一个备忘录即可。下面是一个示例代码:

public class TextEditor {
  private String text;
  private Caretaker caretaker;
  public TextEditor(String text) {
    this.text = text;
    caretaker = new Caretaker();
  }
  public void updateText(String text) {
    caretaker.addMemento(new Memento(this.text));
    this.text = text;
  }
  public void undo() {
    Memento memento = caretaker.getMemento();
    text = memento.getState();
  }
  public String getText()
    return text;
  
}
class Memento {
  private String state;
  public Memento(String state)
    this.state = state;
  
  public String getState()
    return state;
  
}
class Caretaker {
  private Stack
  mementos;
 
  public Caretaker() {
    mementos = new Stack<>();
  }
  public void addMemento(Memento memento) {
    mementos.push(memento);
  }
  public Memento getMemento() {
    return mementos.pop();
  }
}

上述代码中,我们定义了一个TextEditor类,用于编辑文本。每当我们修改文本时,都将当前状态保存在一个备忘录中。当我们需要撤销时,调用undo方法即可回到上一个备忘录状态。

3. 利用命令模式实现撤销

我们也可以利用命令模式来实现撤销操作。命令模式是一种行为型模式,用于将一个请求封装成一个对象,从而使我们能够更好地控制请求的生命周期。我们可以在每次操作之前创建一个Command对象,并将其存储在一个历史列表中。当需要撤销时,我们只需要取出上一个Command对象并调用其undo方法。下面是一个示例代码:

public class FileOperation {
  private List history;
  public FileOperation() {
    history = new ArrayList<>();
  }
  public void performCommand(Command command) {
    command.execute();
    history.add(command);
  }
  public void undo() {
    if (!history.isEmpty()) {
      Command command = history.remove(history.size() - 1);
      command.undo();
    }
  }
}
interface Command {
  void execute();
  void undo();
}
class DeleteFileCommand implements Command {
  private File file;
  public DeleteFileCommand(File file)
    this.file = file;
  
  @Override
  public void execute() {
    if (!file.delete()) {
      throw new RuntimeException("Unable to delete file: " + file.getAbsolutePath());
    }
  }
  @Override
  public void undo() {
    try {
      file.createNewFile();
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
}

上述代码中,我们定义了一个FileOperation类,用于操作文件。每当我们执行一个操作时,都将其包装成一个Command对象,并将其存储在history列表中。当需要撤销时,取出上一个Command对象并执行其undo方法即可。

  
  

评论区