Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Command Pattern seems needlessly complex (what am I failing to understand?)

I've read up on the Command Pattern, and I think I'm missing something. The Command object exists to abstract away the details of the Receiver object. It seems to me that we could simply stop here, and hold references to Command objects to execute the appropriate method at the appropriate time.

Why, then, is the Invoker needed? What advantage does this additional indirection provide? We've already hidden the details of the Receiver behind the Command, what's the motivation for the Command to then be hidden from the client as well?

like image 272
Chris Tonkinson Avatar asked May 19 '11 19:05

Chris Tonkinson


People also ask

What problem does command pattern solve?

The command design pattern is one of the twenty-three well-known GoF design patterns that describe how to solve recurring design problems to design flexible and reusable object-oriented software, that is, objects that are easier to implement, change, test, and reuse.

What is the motivation behind the Command design pattern?

The main motivation for using the Command pattern is that the executor of the command does not need to know anything at all about what the command is, what context information it needs on or what it does. All of that is encapsulated in the command.

What is the command pattern good for?

Use the Command pattern when you want to parametrize objects with operations. The Command pattern can turn a specific method call into a stand-alone object. This change opens up a lot of interesting uses: you can pass commands as method arguments, store them inside other objects, switch linked commands at runtime, etc.

What is the difference between command and strategy pattern?

The main difference is , the command does some action over the object. It may change the state of an object. While Strategy decides how to process the object. It encapsulates some business logic.


2 Answers

If you are passing different type of commands, Invoker is useful. You can use same Invoker for execution of different concrete commands. On a different node, tagging Receiver with ConcreteCommand instead of Invoker allows loose coupling. The Receiver may change the name of the method (e.g. switchOn to swithcOnTV) as in this example:

Related post: Using Command Design pattern

To understand the purpose of Invoker,I would like you to refer this article on Restaurant & Car Service centre use cases.

The waiter (Invoker) takes the order from the Customer on his pad. The Order is then queued for the order cook and gets to the cook (Receiver) where it is processed.

The Client is the Customer. He sends his request to the Receiver through the waiter, who is the Invoker. The waiter encapsulates the command (the order in this case) by writing it on the check and then places it, creating the ConcreteCommand object which is the command itself.

The Receiver will be the cook that, after completing work on all the orders that were sent to him before the command in question, starts work on it.

Another noticeable aspect of the example is the fact that the pad for the orders does not support only orders from the menu, so it can support commands to cook many different items.

like image 107
Ravindra babu Avatar answered Nov 05 '22 17:11

Ravindra babu


Well, if you put it that way, it seems quite complex, but often a Receiver doesn't need to be an object at all. It can be little more than just a function that is executed (as an event). Also, the invoker doesn't need to be a class. It is just the thing that triggers the command. This also can be an event handler in a button.

Even Wikipedia sums up a couple of examples where this pattern is used without actually having to implement complete separate classes for invoker and receiver. An example is a wizard dialog, where the GUI populates the command object, and a Finish button triggers it. So that GUI class (that you have anyway) is both the client and the invoker.

like image 24
GolezTrol Avatar answered Nov 05 '22 17:11

GolezTrol