面试题答案
一键面试关键类的修改或新增
- 命令接口(Command Interface):
- 需要在命令接口中添加一个
undo
方法,用于执行撤销操作。
public interface Command { void execute(); void undo(); }
- 需要在命令接口中添加一个
- 具体命令类(Concrete Command Classes):
- 每个具体命令类除了实现
execute
方法外,还需要实现undo
方法。在undo
方法中,通常需要反转execute
方法所执行的操作。例如,如果execute
方法是增加某个值,undo
方法则减少该值。
public class ConcreteCommand implements Command { private Receiver receiver; private int stateBeforeExecute; public ConcreteCommand(Receiver receiver) { this.receiver = receiver; } @Override public void execute() { stateBeforeExecute = receiver.getState(); receiver.action(); } @Override public void undo() { receiver.setState(stateBeforeExecute); } }
- 每个具体命令类除了实现
- 调用者类(Invoker Class):
- 调用者类需要维护一个命令历史记录栈,以便在需要时能够取出最近执行的命令并调用其
undo
方法。
import java.util.Stack; public class Invoker { private Stack<Command> commandStack = new Stack<>(); public void executeCommand(Command command) { command.execute(); commandStack.push(command); } public void undoLastCommand() { if (!commandStack.isEmpty()) { Command command = commandStack.pop(); command.undo(); } } }
- 调用者类需要维护一个命令历史记录栈,以便在需要时能够取出最近执行的命令并调用其
- 接收者类(Receiver Class):
- 接收者类可能需要提供一些额外的方法,以便具体命令类的
undo
方法能够反转操作。例如,提供获取和设置状态的方法,如上述ConcreteCommand
类中用到的getState
和setState
方法。
public class Receiver { private int state; public void action() { state++; } public int getState() { return state; } public void setState(int state) { this.state = state; } }
- 接收者类可能需要提供一些额外的方法,以便具体命令类的
核心代码示例
- 测试代码:
public class Main { public static void main(String[] args) { Receiver receiver = new Receiver(); Command command = new ConcreteCommand(receiver); Invoker invoker = new Invoker(); invoker.executeCommand(command); System.out.println("After execute, state: " + receiver.getState()); invoker.undoLastCommand(); System.out.println("After undo, state: " + receiver.getState()); } }
在上述代码中,通过对命令模式中关键类的修改和新增,实现了撤销操作的功能。命令接口添加了undo
方法,具体命令类实现了该方法以反转操作,调用者类维护命令历史记录栈来支持撤销操作,接收者类提供了必要的方法协助具体命令类完成撤销。