努力理解如何用Java实现命令模式设计
作为项目的一部分,我必须重构一些代码,我想我应该实现一个命令模式设计,但我从多个角度看了它,并不断遇到问题。到目前为止,我只是想从零开始创建一些小东西,但拥有我认为它需要的所有功能 我需要创建一个可以运行编辑器的程序,反复向用户请求命令,解析这些命令并调用相应的函数,直到调用“quit”命令,然后程序退出。需要的一些功能包括:正在工作的“currentImage”(例如命令可能是、open、save、mono等),可以存储已工作图像的“缓存”(我可以在其中“获取”和“放置”图像),将一个图像置于另一个图像之上的命令,如“上面” 如果我有这样一个编辑器类:努力理解如何用Java实现命令模式设计,java,command-pattern,Java,Command Pattern,作为项目的一部分,我必须重构一些代码,我想我应该实现一个命令模式设计,但我从多个角度看了它,并不断遇到问题。到目前为止,我只是想从零开始创建一些小东西,但拥有我认为它需要的所有功能 我需要创建一个可以运行编辑器的程序,反复向用户请求命令,解析这些命令并调用相应的函数,直到调用“quit”命令,然后程序退出。需要的一些功能包括:正在工作的“currentImage”(例如命令可能是、open、save、mono等),可以存储已工作图像的“缓存”(我可以在其中“获取”和“放置”图像),将一个图像置于
public class Editor {
private ArrayList<Image> cache;
private Image currentImage;
private Parser parser;
public Editor(){
cache = new ArrayList<Image>();
parser = new Parser();
}
public void edit() {
boolean finished = false;
while (!finished) {
command = parser.getCommand();
finished = command.execute(command.getArgs())
}
}
public boolean aNormalCommand(SomeType args) {
//Do interesting things with args
return false;
}
public boolean quit(SomeType args) {
//Check that the args make sense
return true;
}
//
// more normal functions
//
}
public int processCommand(String command) {
for (Command commandObject : listOfCommands) {
if (commandObject.isCommand(command)) {
if (commandObject.processCommand(command)) {
int response = commandObject.executeCommand();
return response;
} else {
return -1;
}
}
}
return -2;
}
公共类编辑器{
私有ArrayList缓存;
私人形象;
专用解析器;
公共编辑(){
cache=newarraylist();
parser=newparser();
}
公共作废编辑(){
布尔完成=假;
当(!完成){
command=parser.getCommand();
finished=command.execute(command.getArgs())
}
}
公共布尔命令(SomeType args){
//用args做有趣的事情
返回false;
}
公共布尔退出(SomeType args){
//检查args是否有意义
返回true;
}
//
//更正常的功能
//
}
我一直坚持的事情:
- 如何实际使其执行所需的命令
- 如何正确解析输入,以便检查传入有效命令的用户。我已经研究了如何使用枚举和/或哈希映射
- 如何使添加新功能变得简单
希望您能告诉我,我的编辑器类不应该是这样的,一切都会井然有序。您的编辑器类必须包含执行所需命令所需的字段 所需的一些功能包括:正在使用的“currentImage”(示例命令可能是、open、save、mono等) 编辑器类中有一个当前图像。它可能需要是一个BuffereImage,以便您可以执行某些命令 一个“缓存”,用于存储处理过的图像(我可以在其中“获取”和“放置”图像) 创建缓存的一种方法是创建一个BuffereImage列表 将一个图像置于另一个图像之上的命令,如“over” 现在,BuffereImage必须具有位置信息。您可能需要创建一个子类来保存位置信息和BuffereImage的点或矩形 一旦有了一个包含所有必需字段(包括任何子类)的类,就可以为命令创建一个接口。这里有一个例子
public interface Command {
public boolean isCommand(String command);
public boolean processCommand(String command);
public int executeCommand();
}
isCommand方法标识该命令。“撤消”就是一个例子。对于“Undo”命令字符串,Undo类将返回true
processCommand方法解析该命令。“将图像3移动到位置5”是必须解析的命令示例。如果命令正确解析和验证,则返回true,否则返回false
executeCommand执行该命令。返回一些指示符以指示命令正确执行。我用了一个int。你可以用一个enum
编辑器类将通过构造函数传递给实现该命令接口的具体类
在一个模型类中,创建命令实例列表。然后将实现命令接口的具体类添加到列表中
您可以这样处理命令:
public class Editor {
private ArrayList<Image> cache;
private Image currentImage;
private Parser parser;
public Editor(){
cache = new ArrayList<Image>();
parser = new Parser();
}
public void edit() {
boolean finished = false;
while (!finished) {
command = parser.getCommand();
finished = command.execute(command.getArgs())
}
}
public boolean aNormalCommand(SomeType args) {
//Do interesting things with args
return false;
}
public boolean quit(SomeType args) {
//Check that the args make sense
return true;
}
//
// more normal functions
//
}
public int processCommand(String command) {
for (Command commandObject : listOfCommands) {
if (commandObject.isCommand(command)) {
if (commandObject.processCommand(command)) {
int response = commandObject.executeCommand();
return response;
} else {
return -1;
}
}
}
return -2;
}
我不太了解您在表示“更改当前图像”命令的类中看到的问题。你能详细说明一下吗?因为那个类(改变当前图像)需要保存调用该类的对象(编辑器)。可能吗?为什么?如果其他类型的命令不需要保存对其应用的编辑器的引用,为什么一种命令需要保存对该编辑器的引用?我认为您在这里做出了一些非强制性的实现假设。然而,是的,命令对象可以保存对其目标编辑器的引用。如果它的类是
Editor
的内部类,它甚至会自动得到这个结果。我在看buyStock.java和sellStock.java。他们都持有股票。在我的例子中,是编辑器还是图像。它需要在那里执行,我不确定我是否很喜欢这个例子。我也不认为这是一个很好的模拟程序,你正在工作。在任何情况下,尽管您的命令对象确实需要知道要操作的Editor
,但它们不一定需要它作为成员变量。它可以作为参数提供给他们的do()
和undo()