GoF Definition: Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
Here requests are encapsulated as objects. In general, four terms are associated—invoker, client, command, and receiver. A command object is capable of calling a particular method in the receiver. It stores the parameters of the methods in receiver. An invoker only knows about the command interface, but it is totally unware about the concrete commands. The client object holds the invoker object and the command object(s). The client decides which of these commands needs to execute at a particular point in time. To do that, he/she passes the command object to the invoker to execute that particular command.
We cannot change our past, but frequently we wish we could do so. Unfortunately, we do not have any such device yet to fulfill that wish. But we can undo and redo many other operations in our daily life. We can erase a pencil drawing with a rubber. We can re-architect our living places. And, most important, we can forget bad memories and start a fresh journey. So, you must acknowledge that undo/redo operations are part of our life and we are doing those through some commands—either externally or internally.
The above scenario applies with Microsoft paint also. There we can do the undo/redo operations easily through some menu options or shortcut keys.
Consider this simple example in this context. For simplicity, we are dealing with only two commands, MyUndoCommand and MyRedoCommand. All naming conventions are used for your easy reference.
High-level structure of the parts of the program is as follows:
package command.pattern.demo;
interface ICommand
{
void Do();
}
class MyUndoCommand implements ICommand
{
private Receiver receiver;
MyUndoCommand(Receiver recv)
{
receiver=recv;
}
@Override
public void Do()
{
//Call undo in receiver
receiver.performUndo();
}
}
class MyRedoCommand implements ICommand
{
private Receiver receiver;
MyRedoCommand(Receiver recv)
{
receiver=recv;
}
@Override
public void Do()
{
//Call redo in receiver
receiver.performRedo();
}
}
//Receiver Class
class Receiver
{
public void performUndo()
{
System.out.println("Executing -MyUndoCommand");
}
public void performRedo()
{
System.out.println("Executing -MyRedoCommand");
}
}
//Invoker Class
class Invoke
{
ICommand cmd;
public void ExecuteCommand(ICommand cmd)
{
this.cmd=cmd;
cmd.Do();
}
}
//Client Class
class CommandPatternEx
{
public static void main(String[] args)
{
System.out.println("***Command Pattern Demo*** ");
Receiver intendedreceiver=new Receiver();
/*Client holds Invoker and Command Objects*/
Invoke inv = new Invoke();
MyUndoCommand unCmd = new MyUndoCommand(intendedreceiver);
MyRedoCommand reCmd = new MyRedoCommand(intendedreceiver);
inv.ExecuteCommand(unCmd);
inv.ExecuteCommand(reCmd);
}
}