在命令设计模式中将上下文传递给执行方法

Kar*_*nna 3 java design-patterns

通过命令设计模式,我明白我们需要通过构造函数设置上下文来创建命令,然后调用执行方法对上下文执行某些操作。例子:

public class Command implements ICommand {

    Device device;

    public Command(Device device) {
        this.device = device;
    }

    public void execute() {
        this.device.turnOn()
    }
}
Run Code Online (Sandbox Code Playgroud)

我想知道通过这种方法,我们将需要为我们创建的每个设备对象创建一个新的命令对象。将上下文和一些参数传递给execute方法可以吗?我正在寻找类似的东西:

public class Command implements ICommand {

    public void execute(Device device) {
        this.device.turnOn();
    }

}
Run Code Online (Sandbox Code Playgroud)

这种方法有什么问题吗?

Sam*_*Sam 5

命令模式背后的想法是它应该封装执行操作所需的所有信息。这使您可以执行一些操作,例如将操作的执行延迟到稍后时间,甚至在执行后撤消操作。

举一个具体的例子,考虑一下文字处理器中的“撤消”功能。

  1. 每次在文档中键入内容时,应用程序都会使用命令模式来记录操作。
  2. 如果您点击“撤消”,您输入的文本就会消失。
  3. Then, when you hit "Redo", the typed text reappears, without the application needing to ask for the input again. It does this by replaying the command that it stored in step 1, which contains all the information about the text you typed.

If your command object requires additional parameters in order to perform the action, it doesn't really implement the Command pattern. It loses most of the advantages of the Command pattern, because the caller can't execute the action without additional information. In your example, the caller would need to know which device is being turned on.

However, that doesn't mean that you have to stick rigidly to the pattern. If it's more useful in your case for the execute method to accept a Device parameter, that's what you should do! If you do that, you should consider renaming the interface, though. Referring to it as a Command pattern when it doesn't follow the pattern exactly could confuse other readers of the code.


When deciding whether to take an object in as a method parameter or a constructor parameter, one of the things I find most helpful is to consider how I'm going to test the application. Objects that form part of the initial setup of the test get passed in as constructor parameters, while objects that form the inputs of the test, or the test vector, are method parameters. I find that following that guideline helps to produce maintainable code.