Wednesday, June 29, 2022

How to implement Command Design Pattern in Java with Example

Hello guys, it's been a long since I have shared a Java design pattern tutorial. I did share some courses to learn design patterns but haven't really talked about a particular design pattern in depth. So, today, we'll learn one of the important design pattern, which is often overlooked by Java developers. Yes, I am talking about the Command Pattern which can help you write flexible, loosely coupled code for implementing actions and events in your application. In simple words, the command design pattern is used to separate a request for action from the object which actually performs the action. This decoupling between Invoker and Receiver objects provides a uniform way to perform different types of actions. This decoupling is achieved using a Command object, which is usually an interface with methods like execute()

The Requestor or Invoker only knows about the Command object and doesn't care about the actual object which processes the request, which can be different. This transparency leads to cleaner code on the Invoker side and also enables the opportunity to do several smart things on the Command side.

Your Command object can be as dumb as simply delegating the request to Receiver and can be as smart as recording the last command for performing UNDO and REDO functionality.

The Command pattern ensures that your code is compliant with open closed design principles, the O of SOLID design principles, which means adding a new command would be very easy, creating a new implementation of the Command interface and doesn't affect the Invoker code.

The command pattern is particularly popular in GUI applications, where we use lots of commands like Open, Close, Save, Cut, Copy, Paste, and corresponding UNDO and REDO operations. You can also see these Java Design Patterns course which not only covers the command pattern and recently been updated to cover Java SE 8 as well.





1. Command Pattern Terminology

Before going further and implementing a command pattern in Java, let's get familiar with the terminology used in this pattern.
  • Client - Creates Concrete Command Object and configure with Receiver
  • Invoker - Who hold command and calls execute() method on Command object
  • Receiver - Actual object, which processes the request
  • Command - Interface, which takes a request from Invoker and delegates to Receiver
  • ConcreteCommand - implementation of Command interface for doing a particular task

UML Diagram of the Command Design Pattern

Here is the UML diagram of the Command Design Pattern, which will make things more clear.

You can see that Client has a reference of a CallbackInterface which has a generic method execute(). The individual commands implement this interface and provide an implementation which is nothing but delegating to the actual object for doing things.

The important thing is that the client doesn't know about the Actual object which is performing an action on behalf of those commands. This decoupling results in flexible code and makes it easy to add new commands without impacting client code.


command design pattern in Java - UML diagram



This is possible because of the open-closed design principles which make the code open for extension but closed for modification. If you are curious to learn more about this principle or in general SOLID design principles, I suggest you take a look at the SOLID Principles of Object-Oriented Design course on Pluralsight. One of my favorite courses and I highly recommend it to every developer who wants to write better, flexible, and clean code.





2. Command Design Pattern in Java - Example

Here is our sample program to demonstrate how to use the command pattern in Java.

This class represent Client of Command pattern

Client.java


import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Java program to implement Command design pattern with example.
 * 
 * @author Javin Paul
 */
public class Client {

    private static final Logger logger = LoggerFactory.getLogger(Client.class);

    public static void main(String args[]) {
       
      // Client creates Invoker object, command object and configure them 
      Menu menu = new Menu();
      menu.setCommand("Create", new CreateCommand());
      menu.setCommand("Delete", new DeleteCommand());
     
      //Invoker invokes command
      menu.runCommand("Create");
      menu.runCommand("Delete");
    }

  
}
Output:
Creating file
Deleting file


This class represents a command

Menu.java 


/*
 * Invoker class, which holds command object and invokes method
 */
public class Menu{
    Map menuItems = new HashMap();
   
    public void setCommand(String operation, Command cmd){
        menuItems.put(operation, cmd);
    }
   
    public void runCommand(String operation){
        menuItems.get(operation).execute();
    }
 
}

An interface to represent commands :

Command.java

/*
 * Command interface for implementing concrete command
 */
interface Command{
    public void execute();
}

Some implementation of command interface, this command will delete files

DeleteCommand.java

/*
 * Concrete command to delete files
 */
public class DeleteCommand implements Command{

    @Override
    public void execute() {
        System.out.println("Deleting file");
    }
}

Another implementation of the command interface to create files :

CreateCommand.java

/*
 * Concrete command to create file
 */
public class CreateCommand implements Command{
   
    @Override
    public void execute() {
        System.out.println("Creating file");
    }
}

You can see we have created two commands Create and Delete by using Command pattern. It's one of the GOF patterns as well.

You can see Command is an interface and both CreateCommand and DeleteCommand implement that interface and implements execute() method to put the logic of what command is supposed to do.

Knowledge of design patterns really helps to write more flexible and better code and if you also feel like that I suggest you go through all object-oriented design patterns at least once. If you want an online course, I suggest joining the Design Pattern Library course on Pluralsight It provides the best collection of the object-oriented design pattern.

How to implement Command design Pattern in Java with Example




3. Real-world Examples of Command Pattern in Java

One of the best way to learn and understand the design patterns is by exploring as many real-life examples as possible. Seeing, how a particular framework like Spring,  project, or library uses a pattern that helps to develop an insight required to identify use cases, where a pattern can be applied.

Recently, I have also shared, how I learned template method pattern and a couple of design principles from Spring farmwork on my post 3 things Java developers can learn from Spring to write better code.

Whenever I learn a new design pattern, I always look in the core Java library for it's used. Since every Java programmer uses JDK library daily basis, chances of connecting to an example are more than any random trivial example.

Two of the Command pattern examples from JDK are java.lang.Runnable and javax.swing.Action interface. If you look closely you will find that Thread Pool executors are invoker of Runnable commands.






4. Benefits of Command Design Pattern

As we have seen in this article, the main benefit of using the Command pattern in Java is decoupling the Invoker of a command from the object, which does the actual processing. By decoupling them and using introducing Command object, we create a design which can keep track of every state changed via Command objects.

This knowledge can be used for useful purpose e.g. implementing UNDO and REDO operations, recording or queuing of request, etc. In short command design pattern provides the following advantages :

1) Encapsulate request processing.

2) Decouples clients from an object which actually processes the request and provides a uniform way to perform a similar task.

3) Since Command pattern encapsulates request, It can be used to record state, implement Undo and redo functionality, Queuing a request, etc.

4) Command Pattern makes it easy to add new commands. It also follows the Open Closed design principle, where new functionality is added by creating a new code. Since request processing is transparent to Invoker, adding a new command doesn't require a change on their side.

Btw, so far. I have suggested some nice courses to learn further about design patterns but if you like books you can always see the Head First design pattern 2nd edition for more real-world examples of the command design pattern in Java.

One of the best books to learn object-oriented design patterns, which is also now updated for Java 8 to implement those patterns in a better way.

how to implement command design pattern in Java



5. Cons of the Command Pattern

Like any other design decision, the Command pattern also involves tradeoffs. If you have a lot of commands, just like in a major GUI application like popular Java IDEs like Eclipse or IntelliJIDEA, you might end up with lots of small command classes.

Though similar functionality can be grouped into a couple of classes with each method performing a task for a particular command.

 By the way, using the Command pattern result in readable, maintainable, and extensible code, so this cost is worth paying.


That's all about Command pattern in Java and Object-oriented programming. Use the Command pattern to encapsulate request processing and separating the invocation of a method from the object, which actually processes that request.

The Command design pattern can also be used for doing smart things instead of just delegating the request to the Receiver, like. you can record and queue up the request for processing, can perform undo operations, and can perform pre-processing operation e.g. logging request for auditing, etc.


Other Java Design Patterns tutorials you may like
  • 5 Free Courses to learn Object Oriented Programming (courses)
  • Difference between Factory and Dependency Injection Pattern? (answer)
  • 7 Best Courses to learn Design Pattern in Java (courses)
  • How to create thread-safe Singleton in Java (example)
  • 7 Best Books to learn the Design Pattern in Java? (books)
  • How to implement the Strategy Design Pattern in Java? (example)
  • Difference between Factory and AbstractFactory Pattern? (example)
  • 18 Java Design Pattern Interview Questions with Answers (list)
  • How to design a Vending Machine in Java? (questions)
  • 20 System Design Interview Questions (list)
  • Difference between State and Strategy Design Pattern in Java? (answer)
  • Top 5 Courses to learn Design Patterns in Java (courses)
  • 5 Free Courses to learn Data Structure and Algorithms (courses)

Thanks a lot for reading this article so far. If you like this Java design pattern tutorial then please share it with your friends and colleagues. If you have any questions or feedback then please drop a note.

P. S. - If you are keen to learn Design patterns in Java but looking for a free online training course to start with then you can also check out this Java Design Pattern and Architecture course on Udemy. It's completely free and you just need a free Udemy account to join this course.

7 comments:

  1. Does command pattern has a real world usage in finance and insurance domain? I see it is more useful to implements command and action hence more suitable for game programming domain, and particularly in GUI application.

    ReplyDelete
  2. what is Receiver in this program...

    ReplyDelete
  3. Which is Receiver Class in this program

    ReplyDelete
  4. Shouldn't Menu not be an Invoker instead of a Command?

    ReplyDelete
  5. Yes, Menu is a n Invoker or Receiver

    ReplyDelete
  6. Create a command interface. Order.java public interface Order { void execute(); }
    Create a request class. ...
    Create concrete classes implementing the Order interface. ...
    Create command invoker class. ...
    Use the Broker class to take and execute commands. ...
    Verify the output.

    ReplyDelete