I am familiar with Command pattern but one aspect has always bothered me. The Gang of Four book (along with other sources) claims the requestors "don't know which subclass of Command they use". Something, a factory or otherwise, has to know this and the information about which Command instance is being used must ultimately originate with the requestor, who needs to make the right call. Just for reference I've lifted sample code off of Steven Haines blog (http://www.informit.com/guides/content.aspx?g=java&seqNum=481). Here listing 5 is the requestor. The whole premise of the "requestor not knowing anything about the about the Command" claim has always seemed kind of hokey and contrived. Can anybody help me out? Thanks.
Thanks for the response. I guess my point is that the coupling between the Command implementation and the information pointing to it has to occur somewhere. In your example, it occurs in the map definition. A line like:
commands.put("UP", new MoveUpCommand());
is coupling the string "UP" to the MoveUpCommand instance. The requestor to has to know that the string "UP" refers to a certain implementation. Therefore, the requestor must know something about the implementation. It is not completely ignorant as people claim. I would be fine if literature said "a requestor doesn't need to directly know of the Command implementation" but it is the claim of complete seperation which baffles me.
It may seem like knitpicking but it is really an important distinction (at least until my mind gets preoccupied with something else).
author and iconoclast
Now all the knowledge about what commands are implemented in what class is held in a text file, not in code. You can change the text file without recompiling any code. You can add commands without modifying a single line of existing code. You can have three different text files for three different versions of the game. You can record scripts that are just lists of commands; the engine that executes those scripts, again, doesn't need to know a thing about any of the actual command classes.
This is not starting to sound completely separated?
John Eric Hamacher wrote:Thanks for the response. I guess my point is that the coupling between the Command implementation and the information pointing to it has to occur somewhere. In your example, it occurs in the map definition. A line like:
commands.put("UP", new MoveUpCommand());
But that can be pushed arbitrarily farther from code that uses it. For example you could generate an XML file with a list of command words -> command class name mappings. Then your factory reads the XML file, loads and instantiates the classes referred to by the XML and responds to requests. It never needs to know what either is.
is coupling the string "UP" to the MoveUpCommand instance. The requestor to has to know that the string "UP" refers to a certain implementation.
No, the requester does not care about implementation details. It just needs to know that it wants to do 'UP' and lets the controller take care of what 'UP' means.
Therefore, the requestor must know something about the implementation.
Nope, the requester just needs to know what it is allowed to do (what commands exists in the context under which it runs). It need know nothing about implementation. Imagine that same XML file which maps command words to command classes. The command factory creates a list of Strings which are valid commands. The controller passes this list of commands to the requester so it knows what it can do. No where in code does it need to know what the command words are. The requester is always at least one step removed from the implementation (it knows or uses the command word but does not know about the command itself). The controller is is always at least one step away from the implementation as well. It knows the command words and would have a reference to the Command reference - which is an implementation independent interface - but never needs to know anything about the implementing class. The CommandFactory is where it may come together - it may instantiate the instances itself which is fine because you can change implementation or implementing classes in the Factory without affecting any other code as long as the command words stay the same. Alternatively, as with the XML example, the Factory just knows about a configuration file and the file is the only thing that 'knows' about the implementing class so the implementation can change without affecting any code.
It is not completely ignorant as people claim. I would be fine if literature said "a requestor doesn't need to directly know of the Command implementation" but it is the claim of complete seperation which baffles me.
It is completely independent of the implementation. It only needs to know the Command word/name, this has nothing to do with the Command itself - maybe all words map to the same command... maybe they all map to different commands... the requester doesn't even know that there is a Command interface involved.
John Eric Hamacher
Joined: Apr 25, 2007
It does not need to know about the implementation, but it needs to know the piece of information that the implementation is coupled with, which essentially, is a piece of information about the implementation. I completely understand that we can push this coupling away from the requester, but it is still there all the same. It is impossible to completely and absolutely make this separation complete. From a practical standpoint, this hardly matters. But I'm playing devil's advocate on this one.