17

I don't understand why a Command pattern is convenient in object-oriented design.

Instead of using, e.g. the Command Switch which has a reference to the Lamp class, can't I just create a Switchable abstract class and invoke its methods?

In this way I'm decoupling the invoker and receiver anyway, and I don't have to create a Command object for each receiver class.

jaco0646
  • 11,033
  • 7
  • 47
  • 64
aneuryzm
  • 55,858
  • 96
  • 259
  • 471

8 Answers8

13

Your Switchable creates an abstraction between invoker and receiver but they are still coupled (invoker has needs a reference to the receiver). The Command pattern lets you create that decoupling. The invoker says to some intermediate component "Hey I've got this command I'd like to be executed" and then the intermediate thing can dynamically pass that request on to the receiver.

ps... I'm guessing you pulled the Switch example from wikipedia. That's a pretty bad example of why this pattern is useful. Take a look at a better examples.

Aki la
  • 331
  • 3
  • 17
Robert Levy
  • 27,992
  • 6
  • 59
  • 93
  • 1
    thank you for the example. However, I still don't see the advantage of having a reference to the receiver in the command rather than in the invoker. In other words, why decoupling them is so useful ? In which situations is useful ? – aneuryzm Jun 09 '11 at 18:52
  • Is the main reaso to keep the code maintainable and make the invoker more reusable ? Or there are more practical advantages ? – aneuryzm Jun 09 '11 at 18:53
  • 2
    @Patrick, by keeping them separate you can swap our receivers without having to change the invoker (or vice versa). thus, easier maintainability. there are also scenarios where the connection between invokers and receivers can't be determined until runtime based on config files, user input, or some data source. – Robert Levy Jun 09 '11 at 19:27
  • @RobertLevy I just have a question, why do we need Receiver class in this pattern ? To decouple between ConcreateCommand and Client, is it right ? – duynt Aug 11 '16 at 11:29
9

Suppose you want to make a list like this:

  • Turn on lamp
  • Set A/C temperature
  • Play "Moon River"

The actions and receivers are all different, so you need an abstraction that is decoupled from all of them. The Command pattern also comes in handy when you want to support undo/redo or similar things.

kevin cline
  • 2,426
  • 1
  • 21
  • 33
  • Ok, in the undo/redo context, I understand. But in other situations, why you want to decouple invoker and receiver ? – aneuryzm Jun 09 '11 at 18:51
  • Is because you want to keep the code maintainable and make the invoker more reusable ? Or there are more practical advantages ? – aneuryzm Jun 09 '11 at 18:54
  • +1 for history mechanism and CompositeCommand - two classics. The Command pattern decouples the act of invocation from the detail of invocation. As from the Invoker's side there is only ever Command.execute(), the "do" is separated from the "how." @Patrick , it might help to think of a remote control in the switching example used here, or a waiter taking a customer's order to be processed by a cook. – earcam Dec 03 '12 at 20:33
7

Lets look at it like: When client wants the receiver to execute some task, then client has two options,

  1. Call Receiver and tell him to execute the task.
  2. Call some third party who knows receiver, and third party will pass the message to receiver.

First option looks better, as think of scenario, when there is no waiter to take order in restaurant and you have to go to chef to tell him what you want.

OR suppose you lost your remote and you have to go to TV and manually switch the button.

It provides flexibility so that command can be executed not only in synchronous mode, but also in Asynchronous mode.

jamcoupe
  • 1,363
  • 1
  • 16
  • 29
AKS
  • 1,323
  • 3
  • 16
  • 27
6
You -> Switch -> Light

Here the switch decouples you and the light. So it makes it easier to turn on/off lights using switch. this is use (convenience) in using command pattern.

You - Command Invoker
Switch - Command Manager
Command - Turn On/Off
Light - Actual implementer

If command pattern is not there you have to manually put the light in holder when needed and remove it when not needed.

bharanitharan
  • 2,278
  • 5
  • 28
  • 30
1

No. You can not do the same as a command do with the abstraction. In fact every time you can do the work of a pattern and anything else with another way you can do. But when you change the Switcher from concrete to abstract that you must do this for a right design regardless of command pattern, you are only decoupling the client of switcher form its implementation and not decoupling the switcher(i.e Invoker) from Lamp(i.e. Receiver) because at last you must have a reference to Lamp in the concretes of Switcher that is equals to have it in Switcher. Note is here that the Lamp is a concrete and you can not change it to abstract. So when you have a concrete and you are working with it many time and many other attribute, you must use Command Pattern to decouple the Switcher form Lamp by move dependency of Switcher to Lamp inside Command class and depend Switcher to an intermediate class i.e. Command. In addition I think the sample in Wikipedia is very useful.

1

The command pattern offers a structured way of associating user actions with system commands.

By implementing the Command pattern, you can have a structured technique of storing the user's command and thus allow actions such as undo/redo.

For instance, implementing the Command pattern for a simple text editor (GOF - Chapter 2) would look like this:

enter image description here

By storing a undoRedoPointer, we can achieve the undo/redo operation by increasing/decreasing the counter each time a command is executed without violating the object's encapsulation. This is a result of combining the command and the memento design pattern.

Menelaos Kotsollaris
  • 4,517
  • 6
  • 50
  • 61
0

Think of each 'command' object as a live object or task that knows how to perform something by its own. Your invoker is just a queue or list that can

1) hold all these command objects and

2) execute them in order/fashion that you liked to.

This model is so flexible in terms of a handler, isn't it? The invoker can buffer, prioritize or follow any algorithm when performing the tasks.

user1559625
  • 2,382
  • 2
  • 27
  • 56
0

I believe through Command Pattern multiple invokers can use the same command. For e.g., In case of editor, copy functionality (or algo) is required to be invoked from command (ctrl+c) or from menu.

So if you wouldn't have implemented command pattern, copy algo would have been tightly coupled with ctrl+c command, and would have been difficult for you to reuse to be invoked from editor menu.

So it looks like this ...

Ctrl+C action --> CopyCommand --> Copy algo

Menu copy command --> CopyCOmmand --> Copy algo

As you can see from above, the source of command is changing, but destination is same (copy algo)