Reputation: 383
I am reading the headfirst design patterns book.
I observe that the client is shown analogous to a hotel customer, who creates an
order(command)
object, the waitress(invoker)
picks it and calls its execute()
method which in turn calls the chef's cook() method(chef=receiver)
In the command pattern class diagram, I can see client is associated with Receiver
as well as the ConcreteCommand
class. I am unable to get the example because in real world, a customer is not supposed to know about the cook and set the instructions for him. Other concern is that in the command pattern class diagram, I observe that Client is not shown associated with Invoker, but in the attached java program I can see the Invoker reference in the Client class.
Totally confused about what Client module does in the command pattern. Clear about the rest 4 modules.
Upvotes: 2
Views: 2145
Reputation: 59111
You've stumbled upon the challenge with demonstrating design patterns with analogy, by a single concrete example, or with object diagrams. Except for very simple patterns, the concepts and examples usually don't map perfectly to all useful instances of the pattern.
I highly recommend that you pick several sources to learn any of the more complex design patterns. Every explanation is going to have strengths and weaknesses, and you'll probably get a more accurate picture if you take several viewpoints into account. There are plenty of free sources available on the Internet, so you probably don't need to buy additional books (except, eventually, the original Design Patterns book, for reference purposes).
What isn't clear in the diagram is that the Client
, the Invoker
, and the Receiver
are abstract concepts, and don't have a single form that always applies in every case. In any particular implementation of the command pattern, most of these roles are going to be present (except maybe the Receiver
- it is possible that the command is self-contained). You may even be able to point out a specific bit of code that maps to each of these roles, but it's going to map differently in every application. It may even map differently in separate parts of the same application.
There are parts of the diagram you shared that I have problems with, because they are not always true. The Client
might not directly access or even know about the Receiver
. The Client
might also not know about specific ConcreteCommand
objects. The Client
might know how to ask for an instance of a command, and it might know some information that helps pick the right command. However, the client might in some cases be oblivious to which ConcreteCommand
object was executed, especially if you combine the command pattern with the AbstractFactory
pattern.
in real world, a customer is not supposed to know about the cook and set the instructions for him
Analogies and models tend to break down or become confusing when you compare them strictly to reality. It is best to try to figure out what the model is trying to accomplish, and which possible interpretation of reality that the model is trying to account for.
Also, not all models/analogies are any good :) Sometimes they don't actually get the job done.
I observe that Client is not shown associated with Invoker
This is perfectly valid in some implementations of the pattern. The code that eventually calls execute()
may not be the same code that is capable of accepting actions.
The diagram may show a single box, but in the restaurant analogy, the waiter, the cooks, the busboys, the host, the cashier, etc, are all a part of that Invoker
role.
The problem with the diagram is that the client eventually has to pass the command off to the invoker. The invoker itself might have a way to accomplish this, or there may be some sort of system in between (like a command queue). Either way, in their explanation, the invoker role handles both things, and the client must therefore know about the invoker.
Finally:
What does the client do in Command Pattern?
Client
is responsible for knowing that it wants a command to be doneClient
is responsible for knowing how to pick which command gets done, and get an instance of it (even if the client delegates the actual construction of that ConcreteCommand
to some other part of the system)Client
is responsible for knowing how to pass off a command so that it will eventually be invoked (passing it to some object in the Invoker
role, even if that command eventually gets passed off to some other object that actually calls execute()
)Client
is responsible for actually handing off the command to the Invoker
(whether it is directly handed off, or passed off to some intermediate part of the system first)Upvotes: 2
Reputation: 159114
Read this: http://www.oodesign.com/command-pattern.html
Client creates a ConcreteCommand object and sets its receiver [...] The Client asks for a command to be executed.
It even has sample code that show what the client does:
The client creates some orders for buying and selling stocks (ConcreteCommands). Then the orders are sent to the agent (Invoker). [...]
public class Client { public static void main(String[] args) { StockTrade stock = new StockTrade(); BuyStockOrder bsc = new BuyStockOrder (stock); SellStockOrder ssc = new SellStockOrder (stock); Agent agent = new Agent(); agent.placeOrder(bsc); // Buy Shares agent.placeOrder(ssc); // Sell Shares } }
Upvotes: 2
Reputation: 11100
So the idea of a client is in opposition to the idea of a server. (for get the restaurant metaphor for a minute). The server is the centralized application, the client is the interface presented on a users machine. The client machine or GUI signals wither a receiver (middle man) or your program directly to make things happen.
I hope this makes things a little clearer.
Upvotes: 0