努力了解如何在Java中实现命令模式设计

时间:2015-10-15 15:39:19

标签: java command-pattern

作为项目的一部分,我必须重构一些代码,我认为我应该实现一个命令模式设计,但我从多个角度看待它并继续遇到问题。到目前为止,我只是试图从头开始创建一些小而具有我认为它需要的所有功能的东西。

我需要创建一个可以运行编辑器的程序,反复询问来自用户的命令,解析这些命令并调用相应的函数,直到“退出”为止。命令被调用,然后程序退出。所需的一些功能包括:a' currentImage'正在工作(示例命令可能是,打开,保存,单声道等),'缓存'可以存储处理图像的位置(我可以将图像放到'以及将图像放到哪里),如上面的命令'将一个图像放在另一个图像之上

如果我有一个类似于此的编辑器类:

 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
      //
 }

我坚持的事情:

  • 如何实际执行所需的命令。
  • 如何正确解析输入,以便我可以检查传入有效命令的用户。我已经看过使用枚举和/或散列图。
  • 如何让实际添加新功能变得简单。

当我看到一个命令是一个说实现执行和撤消的接口,然后为每个获取该对象的函数创建类时,我遇到了用户想要更改当前图像的问题 - 将需要额外的东西来切换图像,然后将新对象传递给正确的对象。

当我考虑如何实现lambdas时,我不确定如何使它在正确的对象上工作。当我看到反射时,不知怎的,我的命令需要弄清楚应该对哪个对象采取行动,而且我不知道解析器如何解决这个问题。

至于&#39;撤消&#39;我想过有一个ArrayList来保存过滤器的历史,而undo操作只是让最后一个成为当前的一个(这也解决了具有不可撤销方法的问题)

希望你能告诉我,我的编辑课不应该是这样的,一切都会落实到位。

1 个答案:

答案 0 :(得分:0)

您的编辑器类必须包含执行所需命令所必需的字段。

  

需要的一些功能是:正在使用的'currentImage'(示例命令可能是,打开,保存,单声道等),

您的编辑器类中有当前图像。它可能需要是BufferedImage,因此您可以执行某些命令。

  

可以存储处理图像的“缓存”(我可以“获取”和“放置”图像),

创建缓存的一种方法是拥有一个BufferedImages列表。

  

诸如“上方”之类的命令,将一个图像放在另一个图像之上。

现在,BufferedImage必须有位置信息。您可能需要创建一个子类来保存位置信息和BufferedImage的Point或Rectangle。

一旦你有一个包含所有必要字段的类,包括任何子类,你就可以为你的命令创建一个接口。这是一个例子。

public interface Command {

    public boolean isCommand(String command);
    public boolean processCommand(String command);
    public int executeCommand();

}

isCommand方法标识命令。 “撤消”就是一个例子。对于“撤消”命令字符串,Undo类将返回true。

processCommand方法解析命令。 “将图像3移动到位置5”是必须解析的命令的示例。如果命令正确解析并验证,则返回true,否则返回false。

executeCommand执行命令。返回一些指示符以指示命令正确执行。我用了一个int。你可以使用枚举。

Editor类将通过构造函数传递给实现此Command接口的具体类。

在您的某个模型类中,您将创建一个Command实例列表。然后,将实现Command接口的具体类添加到List中。

您可以像这样处理命令:

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;
}