Introduction to Command Design Pattern (Java, C# Example)

In this article we are going to learn about Command Design Pattern. What is Command pattern? What are the basic principles? How to implement and where we can use this.
I have used Java with Eclipse and C# with VS2010.

What is Command Design Pattern?
In OO design, some time we need to encapsulate method detail info from client as well as decoupling function detail. Command design pattern allows us to complete decoupling between sender and receiver. Where sender refers to function invoker and receiver refers to function receiver(who gets) and executor.
Command pattern encapsulate how method will be execute, what is the exact method name, what are the method details. It does encapsulation as object and allow clients to parameterize different requests, queues or big requests. Because of command pattern's working process, we can easily implement undo and redo operation. Command pattern has mainly 3 Components :
a. Invoker
b. Receiver
c. The Command
Invoker links between commands and receiver. It also stores the command that it passes.
The Receiver receives the request and act to perform the request. By functionality we can understand it is a behavioral pattern. 

The command object actually encapsulate the request. In this way we get flexibility as well as extensibility.(spatial use, when we are designing event functionality on keyword based selenium framework for testing, command patterns helps to create a scenario by providing step by step execution without knowing specific function details).

Command pattern turns a request into an object which can be passed like as other objects. Lets consider a small example(function testing domain).

Suppose we are testing a web site by selenium functional testing. Testing client will instruct test runner to perform step by step without knowing inner detail of the steps, and test runner send the steps by individual command object(as invoker). And , a keyword driven framework object get the command and understand with current webpage's context and execute the specific function that satisfied the command. And, in here if we have a layer architecture and the selenium framework is in server and test runner in client machine, by command patter Test Client can easily execute the test suit without knowing the inner details. This is one of the good use of Command pattern that I have used.

[I got some difficulties to explain in words, i hope my example may cover those]

Basic Principles :
- Each request will be encapsulated in an object
- Request can be saved in a queue. (allowing undo/redo)
- Clients can generate

UML :


How to implement?
Implementation of command pattern is very simple. Let's think about how to implement. As we need single or or set of command, so there will be an interface ICommand representing command and each command will implement that.
And, there will be a invoker which may maintain a list of commands. The stored command may be used to undo/redo operation.
Receiver, who will get the command perform the function. We may implement receiver interface for applying more than one group of receiver .
And, a client who creates command to be performed and sets to receiver.
That means, Client -> Command ->  Invoker -> Receiver , lets see more from example.

Example : Lets think about Android phone. Typically a android phone contains 6 buttons (considering touch & non touch). Usually buttons are, power button( long press = on/off, short press = screen on/off), Volume +, Volume -, Home key(shows home screen), menu (shows options), back(undo previous option/go to back where I came from). And globally, touch pad, where we touch and out app starts.
Now, see the basic functions of those buttons. Power, volumes, home screen these three have fixed command but, menu and back buttons functions used to change (depend on which app you are currently working). So, from client, we only press those button and ask for the command that is applicable for the specific running application. Let's consider a client who will do all operation(power on,, off, volume Up & Down, back and home button press) and some time undo operation. I will explain this example applying Command pattern step by step.

Step 1 : Receiver Constriction: I have use an IReceiver interface and implementing class MobileReceiver which have the method detail of all tasks. It might be a single class or even a group of class.

public interface IReceiver {
    public void home();
    public void on();
    public void off();
    public void volumeUp();
    public void volumeDowne();
    public void back();
}

public class MobileReceiver implements IReceiver{
    private int vol = 0;
    public void home() {
        System.out.println("You are now at Home Screen");        
    }
    public void on() {
        System.out.println("Mobile is turning on");        
    }
    public void off() {
        System.out.println("Mobile is turning off");        
    }
    public void volumeUp() {
        vol++;
        System.out.println("The volume is up to "+vol);        
    }
    public void volumeDowne() {
        vol--;
        System.out.println("The volume is down to "+vol);        
    }
    public void back() {
        System.out.println("Going Back...");
    }
}
 
Step 2 : Command Generation: We need a command interface that has all method which will be implement by all commands where each command represents each method of receiver class(or group of receivers) . So, the ICommand interface

public interface ICommand {
    public void execute();
    public void undo();//in android mobile, back button refers to undo if any command do not have inverse function(like volume has + & - or power button has On & off
}
Now, the command objects. Each object will represent each function.
public class PressHome implements ICommand{
    private IReceiver myReceiver  = null;
    public PressHome(IReceiver aReceiver ){
        myReceiver= aReceiver ;        
    }
    public void execute() {
        myReceiver.home();    
    }
    public void undo() {
        myReceiver.back();
    }
}

public class PressBack implements ICommand{
    private IReceiver myReceiver  = null;
    public PressBack(IReceiver aReceiver ){
        myReceiver= aReceiver ;        
    }
    public void execute() {
        myReceiver.back();
    }
    public void undo()// Usually back is the undo it self.
    {
        myReceiver.back();
    }
}

public class TurnMobileOff implements ICommand{
    private IReceiver myReceiver  = null;
    public TurnMobileOff(IReceiver aReceiver ){
        myReceiver= aReceiver ;        
    }
    public void execute() {
        myReceiver.off();    
    }
    public void undo() {
        myReceiver.on();
    }
}
 
public class TurnMobileOn implements ICommand{
    private IReceiver myReceiver  = null;
    public TurnMobileOn(IReceiver aReceiver ){
        myReceiver= aReceiver ;        
    }
    public void execute() {
        myReceiver.on();    
    }
    public void undo() {
        myReceiver.off();
    }
}
 
public class VolumeUp implements ICommand{
    private IReceiver myReceiver  = null;
    public VolumeUp(IReceiver aReceiver ){
        myReceiver= aReceiver ;        
    }
    public void execute() {
        myReceiver.volumeUp();;    
    }
    public void undo() {
        myReceiver.volumeDowne();;
    }
}
 
public class VolumeDown  implements ICommand{
    private IReceiver myReceiver  = null;
    public VolumeDown(IReceiver aReceiver ){
        myReceiver= aReceiver ;        
    }
    public void execute() {
        myReceiver.volumeDowne();    
    }
    public void undo() {
        myReceiver.volumeUp();
    }
}
 
Step 3 : Invoker Generation: We have commands and receiver. Now, need invoker. As we know invoker allow client call any command, so it will contain a command object(as element, ICommand). And, we can apply Undo operation by keeping a operation list. When ever we want we can call back the function from the list. I have applied differently. I use a separate method undo(mentioned in ICommand as not all button have same undo procedure, example Volume+ undo will be Volume- but, Home button press undo will be pressing back). This portion is commented(general undo implementation) . But, you can apply that way. I have kept a separate method pressBack(), that calls undo from ICommand. So, the invoker is

public class MobileButtonInvoker {
    private ICommand aCommand;
    //private ArrayList<ICommand> commandQueue = new ArrayList<ICommand>();
    //If we want to apply stack based undo operation, we can keep an array list of ICommands and perform undo by invoker, but I apply that undo in ICommand.
    public MobileButtonInvoker(ICommand newConnand){
        aCommand=newConnand;
    }
    public void press() {
        aCommand.execute();
        //commandQueue.add(aCommand);
    }
    public void pressBack() {
        aCommand.undo();
    }
}


For getting a receiver(mobile), I have added an extra class with static method output. The purpose is only to get us the functional receiver.

public class Mobile {
    public static MobileReceiver getAMobile(){
        return new MobileReceiver();
    }
}


Step 4 : Finally the client who have main method and calls command through invoker.

public class Program {
    public static void main(String[] args) {
        MobileReceiver aMobile= Mobile.getAMobile();
        ICommand command = new TurnMobileOn(aMobile);
        MobileButtonInvoker invoker = new MobileButtonInvoker(command);
        invoker.press();
        command = new PressHome(aMobile);
        invoker = new MobileButtonInvoker(command);
        invoker.press();
        command = new PressBack(aMobile);
        invoker = new MobileButtonInvoker(command);
        invoker.press();
        command = new VolumeUp(aMobile);
        invoker = new MobileButtonInvoker(command);
        invoker.press();
        invoker.press();
        invoker.pressBack();
        command = new VolumeDown(aMobile);
        invoker = new MobileButtonInvoker(command);
        invoker.press();
        command = new TurnMobileOff(aMobile);
        invoker = new MobileButtonInvoker(command);
        invoker.press();
        invoker.pressBack();        
    }
}
 
Java Example :
1. Comment : In android mobile, back button refers to undo if any command do not have inverse function(like volume has + & - or power button has On & off
2. Comment : If we want to apply stack based undo operation, we can keep an array list of ICommands and perform undo by invoker, but I apply that undo in ICommand.
3. I have kept command as generic in client as interface sharing among client is a best practice. 
4. All functions are applied with command line out put to keep it simple.

C# Example :
1. I have change method names as Dot Net works differently than Java.

Uses :
1. By Command pattern, it is easy to make components that needs delegate/sequence /execute method calls at any time without knowing the class of the method or the method parameter.
2. Macro recording and playback, where user actions are kept as command and program records the action as sequence.
3. Remote code execution. If we implement the sequence, we can call method remotely (code will come to client) , similar action to java RMI.
4. UNDO/REDO operation can be done, even if in multiple levels.
5. GUI components that can keep the method in Action command. (spatially helpful in java swing)
6. Progress bars can be implemented by showing number of command performed and associated time
7. Parallel processing, multiple threading, thread pools , in all cases commands are abstracted from thread where a queue of commands are kept for sequence of execution. (undo/redo stacks).

Thanks...:) 

No comments:

Post a Comment