Reputation: 64854
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.
Upvotes: 17
Views: 10373
Reputation: 391
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)
Upvotes: 0
Reputation: 5506
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:
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.
Upvotes: 1
Reputation: 29083
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.
Upvotes: 13
Reputation: 149
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.
Upvotes: 1
Reputation: 2673
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.
Upvotes: 0
Reputation: 2629
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.
Upvotes: 6
Reputation: 1423
Lets look at it like: When client wants the receiver to execute some task, then client has two options,
- Call Receiver and tell him to execute the task.
- 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.
Upvotes: 7
Reputation: 2746
Suppose you want to make a list like this:
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.
Upvotes: 9