如上所述,我目前正在开发一个文本编辑器,就像一个有趣的项目一样。
我现在想要包含一些还原/重做更改功能,但我不知道该怎么做。
我目前的想法:
但是,考虑到大量数据可以很容易地汇集在一起,我不太清楚这是否是最好的方法。但是,我现在还不能弄清楚如何实现这个目标。
是否有任何提示可以让我更好地做到这一点?
答案 0 :(得分:3)
我建议您阅读设计模式,特别是命令模式。以下是一些信息:
Command模式被称为行为模式,因为它用于管理对象之间的算法,关系和责任。最初的Gang of Four关于设计模式的书中提供的Command的定义说明:
将请求封装为对象,从而允许您使用不同的请求,队列或日志请求参数化客户端,并支持可撤消的操作
那么这在类图中意味着什么呢?
Command为所有命令声明一个接口,提供一个简单的execute()方法,该方法要求Receiver执行命令。接收方知道如何执行请求。 Invoker拥有一个命令,可以通过调用execute方法让Command执行请求。客户端创建ConcreteCommands并为命令设置Receiver。 ConcreteCommand定义了动作和接收者之间的绑定。当Invoker调用执行时,ConcreteCommand将在Receiver上运行一个或多个操作。
以下序列图以更清晰的方式显示关系:
我什么时候使用这种模式? 命令模式在以下情况下非常有用:
当您需要进行多次撤消操作时,您会看到命令被大量使用,其中维护了最近执行的一堆命令。要实现撤消,您只需要做的就是获取堆栈中的最后一个命令并执行它的undo()方法。
您还会发现Command对向导,进度条,GUI按钮和菜单操作以及其他事务行为很有用。
那么它在Java中是如何工作的? 我们以遥控器为例。我们的遥控器是家庭自动化的中心,可以控制一切。我们只使用灯光作为示例,我们可以打开或关闭,但我们可以添加更多命令。
首先我们将创建命令界面:
//Command
public interface Command
{
public void execute();
}
现在让我们创建两个具体的命令。一个会打开灯,另一个会关灯:
//Concrete Command
public class LightOnCommand implementsCommand
{
//reference to the light
Light light;
public LightOnCommand(Light light)
{
this.light = light;
}
public void execute()
{
light.switchOn();
}
}
//Concrete Command
public class LightOffCommand implementsCommand
{
//reference to the light
Light light;
public LightOffCommand(Light light)
{
this.light = light;
}
public void execute()
{
light.switchOff();
}
}
Light是我们的接收器类,所以我们现在就设置它:
//Receiver
public class Light
{
private boolean on;
public void switchOn()
{
on = true;
}
public void switchOff()
{
on = false;
}
}
在这种情况下,我们的调用者是遥控器。
//Invoker
public class RemoteControl
{
private Command command;
public void setCommand(Command command)
{
this.command = command;
}
public void pressButton()
{
command.execute();
}
}
最后,我们将设置一个客户端来使用调用程序
//Client
public class Client
{
public static void main(String[] args)
{
RemoteControl control = new RemoteControl();
Light light = new Light();
Command lightsOn = new LightsOnCommand(light);
Command lightsOff = new LightsOffCommand(light);
//switch on
control.setCommand(lightsOn);
control.pressButton();
//switch off
control.setCommand(lightsOff);
control.pressButton();
}
}