Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing context to the execute method in command design pattern

Going through the Command design pattern I understand that we need to create a Command by setting the context via constructor and then calling the execute method to perform some action on the context. Example:

public class Command implements ICommand {

    Device device;

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

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

I was wondering that with this approach we will be required to create a new Command object for every device object we create. Will it be ok to pass the context and some parameters to the execute method? I am looking for something like:

public class Command implements ICommand {

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

}

Are there any issues with this approach?

like image 597
Karan Khanna Avatar asked May 05 '26 21:05

Karan Khanna


1 Answers

The idea behind the Command pattern is that it should encapsulate all the information needed to perform an action. This lets you do things like delay the execution of the action until a later time, or even undo the action after it has been executed.

For a concrete example, consider the "Undo" feature in a word processor.

  1. Each time you type in the document, the application uses the Command pattern to record the action.
  2. If you hit "Undo", the text you typed disappears.
  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.

like image 174
Sam Avatar answered May 08 '26 11:05

Sam



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!