Design Patterns - Command Pattern

As said in the last post, here I'm starting with my first post on Design Pattern implementation in Java.

A Small Intro On Core Design Patterns:
        Many define Pattern with different statements. The most common one: pattern is a solution for common and reoccurring design issue.

The term Pattern was coined by Christopher Alexander in his book, "A Pattern Language: Towns, Buildings, and Construction".
GoF classified patterns based on Purpose and Scope.
Purpose criteria classifies patterns based on what the pattern does:
        1)Creational patterns - dealts with object Creation
        2)Structural patterns - composition of class and objects,
        3)Behavioral patterns - responsibility of class and objects.
Scope classifies based on where it applies to : class or object.


Let me start my series on Design patterns with one of the object behavioral patterns: Command.

Command Pattern:
Command pattern, also called as Action or Transaction pattern deals with decoupling between the invoker and the receiver.
Necessity of Command Pattern occurs when it is needed to invoke a method without knowledge about the method or the object, which holds it. Here, the operation/action to be performed is encapsulated into an object.Command pattern is used to:
    1) Decouple the object with invokes the operation from the object which performs the operation
    2) Combine multiple command in to a Composite command (Macro Command)



Components of Command Pattern:
        The key of command pattern is Command interface (or Abstract Class), which declares the abstract operations. The concrete command class provides implementation details for the operation declared in the Command interface.

UML diagram of Command Pattern:

Example:
        A small description of each of the above elements with implementation details:
. Client: Responsible for creating the Command object and setting the receiver to it.
  
import pattern.command.*;

public class CommandClient {

public static void main(String[] args) {
Receiver receiver = new Receiver();
Command incCommand = new IncrementCommand(receiver);
Command decCommand = new DecrementCommand(receiver);
Invoker invoker = new Invoker();
invoker.setIncCommand(incCommand);
invoker.setDeccCommand(decCommand);

invoker.add();
invoker.add();
invoker.remove();
invoker.add();
invoker.undoAll();
System.out.println(receiver.getValue());
}

}

CommandClient.java

. Invoker: Invokes the execute method of the Command. For implementing undo action, this class keeps track of commands called and performs the undo operation accordingly.

package pattern.command;
import java.util.Stack;

public class Invoker {
Stack commands;
Command incCommand;
Command decCommand;

public Invoker(){
commands = new Stack();
}

public void setIncCommand(Command cmd){
this.incCommand = cmd;
}

public void setDeccCommand(Command cmd){
this.decCommand = cmd;
}

public void undo(){
if(!commands.empty()){
Command cmd = (Command)commands.pop();
cmd.undo();
}
}

public void add(){
incCommand.execute();
commands.add(incCommand);
}

public void remove(){
decCommand.execute();
commands.add(decCommand);
}

public void undoAll(){
Command cmd = null;
while(!commands.empty()){
cmd = (Command)commands.pop();
cmd.undo();
}
}
}

Invoker.java

. Receiver: Class, which preforms the actual functionality.

package pattern.command;

public class Receiver {
private int value = 0;

public int getValue(){
return this.value;
}

public void increment(){
value++;
}

public void decrement(){
value--;
}
}

Receiver.java

. Command: Represents the operation. Implements the execute method which invokes the corresponding operation in the receiver. Defines the binding between the Receiver and action.

package pattern.command;

public interface Command {
public void execute();
public void undo();
}

Command.java


package pattern.command;

public class IncrementCommand implements Command {
private Receiver receiver;

public IncrementCommand(Receiver receiver){
this.receiver = receiver;
}

public void execute() {
receiver.increment();
}

public void undo() {
receiver.decrement();
}

}

IncrementCommand.java


package pattern.command;

public class DecrementCommand implements Command {

private Receiver receiver;

public DecrementCommand(Receiver receiver){
this.receiver = receiver;
}

public void execute() {
receiver.decrement();
}

public void undo() {
receiver.increment();
}

}

DecrementCommand.java

In Real-time:
        The most common example of command pattern implementation is in Swing and Struts.
Command pattern in Swing: When a JButton in the application's window is clicked it invokes the corresponding method in the application code.
Here JButton, a component of Swing has its implementation with in Swings and its not aware of the application's implementation. But the method in the application specific code is called when it is clicked. This method invocation from framework's code to the application code uses command pattern.

Command pattern in Struts: Command pattern is used in the invocation of 'execute/perform' method of specific Action class by struts framework on a request submission from JSP.
During initial stages of development using JSP - Servlets, before the days the frameworks like struts, the Action Servlet / Controller Servlet will have a huge if block to identify each request and then perform the corresponding functionality/method.
Struts replace those if-blocks with command pattern. Struts uses command pattern for evaluation and execution of a method (execute/perform) in the receiver class (Action class).

Comments

Popular posts from this blog

Utilizing WFH Efficiently

Wandering to write..

Back!