About Mainak Goswami

Mainak Goswami is an experienced Technology Consultant specializing in JEE, Web Development and Open source technologies. He is currently based out of United Kingdom. He is a technology enthusiast trying to explore the latest in the world of technology. His current area of interest is Mobility, NoSQL and Cloud computing. In past time he loves blogging on his website Idiotechie.

By your Command – Command design pattern

Command design pattern is one of the widely known design pattern and it falls under the Behavioral Design Pattern (part of Gang of Four). As the name suggests it is related to actions and events in an application.
 
Problem statement:

Imagine a scenario where we have a web page will multiple menus in it. One way of writing this code is to have multiple if else condition and executing the actions on each click of the menu.
 
 

 

 

private void getAction(String action){
	  if(action.equalsIgnoreCase('New')){
		  //Create new file
	  }
	  else if(action.equalsIgnoreCase('Open')){
		  //Open existing file
	  }
	  if(action.equalsIgnoreCase('Print')){
		  //Print the file
	  }
	  if(action.equalsIgnoreCase('Exit')){
		  //get out of the application
	  }
  }

We have to execute the actions based on the action string. However the above code is having too many if conditions and is not readable if it extends further.

Intent:

  • The requestor of the action needs to be decoupled from the object that carries out this action.
  • Allow encapsulation of the request as an object. Note this line as this is very important concept for Command Pattern.
  • Allow storage of the requests in the queue i.e. allows you to store a list of actions that you can execute later.

 
Solution:

To resolve the above problem the Command pattern is here to rescue. As mentioned above the command pattern moves the above action to objects through encapsulation. These objects when executed it executes the command. Here every command is an object. So we will have to create individual classes for each of the menu actions like NewClass, OpenClass, PrintClass, ExitClass. And all these classes inherit from the Parent interface which is the Command interface. This interface (Command interface) abstracts/wraps all the child action classes.
Now we introduce an Invoker class whose main job is to map the action with the classes which have that action. It basically holds the action and get the command to execute a request by calling the execute() method.
Oops!! We missed another stakeholder here. It is the Receiver class. The receiver class has the knowledge of what to do to carry out an operation. The receiver has the knowledge of what to do when the action is performed.

Structure:

Following are the participants of the Command Design pattern:

  • Command – This is an interface for executing an operation.
  • ConcreteCommand – This class extends the Command interface and implements the execute method. This class creates a binding between the action and the receiver.
  • Client – This class creates the ConcreteCommand class and associates it with the receiver.
  • Invoker – This class asks the command to carry out the request.
  • Receiver – This class knows to perform the operation.

 
Example:


 
Steps:

  1. Define a Command interface with a method signature like execute(). In the above example ActionListenerCommand is the command interface having a single execute() method.
  2. Create one or more derived classes that encapsulate some subset of the following: a “receiver” object, the method to invoke, the arguments to pass. In the above example ActionOpen and ActionSave are the Concrete command classes which creates a binding between the receiver and the action. ActionOpen class calls the receiver(in this case the Document class) class’s action method inside the execute(). Thus ordering the receiver class what needs to be done.
  3. Instantiate a Command object for each deferred execution request.
  4. Pass the Command object from the creator to the invoker.
  5. The invoker decides when to execute().
  6. The client instantiates the Receiver object(Document) and the Command objects and allows the invoker to call the command.

 
Code Example:

Command interface:

public interface ActionListenerCommand {
	public void execute();
}

Receiver class:

public class Document {
   public void Open(){
	   System.out.println('Document Opened');
   }
   public void Save(){
	   System.out.println('Document Saved');
   }
}

Concrete Command:

public class ActionOpen implements ActionListenerCommand {
	private Document adoc;

	public ActionOpen(Document doc) {
		this.adoc = doc;
	}
	@Override
	public void execute() {
		adoc.Open();
	}
}

Invoker class:

public class MenuOptions {
	private ActionListenerCommand openCommand;
	private ActionListenerCommand saveCommand;

	public MenuOptions(ActionListenerCommand open, ActionListenerCommand save) {
		this.openCommand = open;
		this.saveCommand = save;
	}
public void clickOpen(){
	openCommand.execute();
}
public void clickSave(){
	saveCommand.execute();
}
}

Client class:

public class Client {
	public static void main(String[] args) {
		Document doc = new Document();
		ActionListenerCommand clickOpen = new ActionOpen(doc);
		ActionListenerCommand clickSave = new ActionSave(doc);
		MenuOptions menu = new MenuOptions(clickOpen, clickSave);
		menu.clickOpen();
		menu.clickSave();
	}

}

 
Benefits:

Command pattern helps to decouple the invoker and the receiver. Receiver is the one which knows how to perform an action.
A command should be able to implement undo and redo operations.
This pattern helps in terms of extensibility as we can add new command without changing existing code.

Drawback:

The main disadvantage of the Command pattern is the increase in the number of classes for each individual command. These items could have been also done through method implementation. However the command pattern classes are more readable than creating multiple methods using if else condition.

Interesting points:

  • Implementations of java.lang.Runnable and javax.swing.Action follows command design pattern.
  • Command can use Memento to maintain the state required for an undo operation.

 
Download Sample Code:

Download Sample Code
 

Reference: By your Command from our JCG partner Mainak Goswami at the Idiotechie blog.

Related Whitepaper:

Bulletproof Java Code: A Practical Strategy for Developing Functional, Reliable, and Secure Java Code

Use Java? If you do, you know that Java software can be used to drive application logic of Web services or Web applications. Perhaps you use it for desktop applications? Or, embedded devices? Whatever your use of Java code, functional errors are the enemy!

To combat this enemy, your team might already perform functional testing. Even so, you're taking significant risks if you have not yet implemented a comprehensive team-wide quality management strategy. Such a strategy alleviates reliability, security, and performance problems to ensure that your code is free of functionality errors.Read this article to learn about this simple four-step strategy that is proven to make Java code more reliable, more secure, and easier to maintain.

Get it Now!  

5 Responses to "By your Command – Command design pattern"

  1. David Illescas says:

    This is a really great article. Thanks.

  2. likish says:

    Okay, I have one question. So does the command have the decision making capability? Like for example, if we have a breakout game and ball, paddle and count up timer that ticks with the game, and I have an update method specific to each of the classes I just mentioned, then would my concrete command class be for UpdateCommand or will it have multiple commands like, OnCollisionWithWallCommand, OnGameOverCommand, OnGameStartCommand, OnGamePauseCommand, etc.?? I think the command shud not have multiple flows, it shud only have one flow which is also told by the client.

    Please let me know if I’m correct.

  3. Srinivasan D says:

    Best article that I read on command pattern. Thanks!

Leave a Reply


two + = 4



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books