Jim's Pages => Java Pages => Command Pattern
The Command Pattern is found in the popular Design Patterns book. Here is the formal definition plus some discussion.
The Command pattern encapsulates an action into an object. To perform the action, you ask the command object to execute and it knows what to do. Commands work well when you manage sub-steps as a transaction, queue commands, pass them around without looking at them, implement undo, and so on.
For example, some GUI toolkits attach commands to menu items. When you select the item, the toolkit executes the command. You can do this in Java Swing as shown in the example below. To implement undo() the command captures the state before executing, and provides an unExecute method to restore the state. The driver can queue up executed commands and unExecute them LIFO.
I used the command pattern in a Scheduler utility. The Scheduler has a collection of schedules, each of which defines a start time, end time and repeat interval for some task. Each schedule is also associated with an arbitrary Object. When it is time to execute a task (start time plus a multiple of interval) the Scheduler publishes a message to interested listeners with the ScheduledEventHandler interface. The handlers have access to the arbitrary Object.
In my first use of the Scheduler, all scheduled events did the same thing, and I made the handler do all the task work.
In a later application I used the Scheduler to schedule a variety of tasks. I made the arbitrary object a Command. The command object has all knowledge of what should happen when the time comes. So the listener to Scheduler events simply calls a method on the Command object, cleverly named execute(). The Command object does all the task work.
This gives me a Scheduler that knows nothing about the task to be executed. And an event handler that knows only that the arbitrary Object implements the ICommand interface with an execute() method. I can schedule any variety of new commands without touching the Scheduler or the handler. Sweet.
Quickly see if you can think of some commands in the real world. The clue is a method like execute() or doRun(). [Proprietary work examples elided] How about standard servlets with doPost() and doGet() methods? In all of these examples, a framework gets a command from a factory using the class name or some key to identify the class. The framework never knows or cares exactly what class it gets, so long as it can call the method to make the command perform its action.
See the VisitorPattern. Is a visitor a command?
This frame actually has more than 10 commands. Before refactoring to use the command pattern, the actionPerformed method had a giant if-else structure to test for every possible event source.
interface ICommand { void execute(); }
private void initCommands()
{
mCommands = new Hashtable();
mCommands.put( mHelp, new ICommand() { public void execute() { new RSCmpHelp().show(); } } );
mCommands.put( mFileOpen, new ICommand() { public void execute() { fileOpen(); } } );
mCommands.put( mFileExit, new ICommand() { public void execute() { processWindowEvent( new WindowEvent( mFrame, WindowEvent.WINDOW_CLOSING ) ); } } );
}
public void actionPerformed(java.awt.event.ActionEvent evt)
{
Object lSource = evt.getSource();
ICommand lCommand = (ICommand)mCommands.get( lSource );
if ( null != lCommand )
lCommand.execute();
else
JOptionPane.showMessageDialog( mFrame, "Command not yet implemented" );
}