Command Pattern — What It Is and How to Use It?

Bhuvnesh Maheshwari
The Startup
Published in
5 min readJan 31, 2021

After a long pause, I am back with yet another design pattern. Today, we will learn the command pattern with an interesting real-world use case. By looking at the name of the pattern what comes to our mind? Any guesses? Well, a command — An army chief gives commands to their soldiers, a caption commands their crews. Hmm, if you think it should be related to the execution of a command, then you are in the right direction. Suppose there are two objects A and B. A wants to request something from B now, command pattern allows us to encapsulate the request. In the command pattern, we encapsulate the request into a standalone object that contains all the information about the execution of the request. Well, but what’s the benefit of doing that?

Let's look at some of those benefits:

  1. We are encapsulating method calls into concrete commands along with important data, not only it makes code much more readable, but also it makes adding and removing commands in a much cleaner way. We don’t need to change the existing classes or methods to add new behaviors. Design principle — The system should be open for extension and closed for modification.
  2. Using a command as an object opens up whole new possibilities. For instance, we can store command objects in a list, stack, set, map, and manipulate them however we want. Now we can easily maintain a history of all the commands or check frequently used commands etc. We can perform the “Undo” of a given command if we have maintained the order of execution. These features are immensely helpful in situations like building games like Chess or Git where we need to roll back and move to the previous state of the application. Also, we can pass commands as method arguments or store them inside other objects.
  3. With the help of a command pattern, we can decouple the logic of execution of the command from the command invoker. Consider this analogy, you go to the restaurant, you order a delicious Cheeseburger, french fries, brownie, and ice cream. The waiter takes an order and writes it on a piece of paper. He will hand the order to a cook, the cook will prepare dishes and ask the waiter to confirm the order and deliver it to the customer’s table. In this whole scenario, the order is our command. The waiter need not know how to prepare dishes, the cook is the only person that is responsible to prepare the recipe. We are separating layers of concerns. Cook prepares the recipe while the waiter takes the order from the customer. Design Principle — Separating layers of concern. ✅

Now, let’s look at the use case of the pattern. Suppose we are working for an eCommerce website. A customer comes to our catalog service and does the following operation.

  1. Add product to a cart — In the backend, a record is inserted in the Cart table.
  2. Do payment — Similarly, the Payments table contains all the transactions by the customers. So we have to record a transaction done by the customer in the payments table.
  3. Create an order — An entry in the order table.
  4. Send the item to logistics — An entry in the logistics table containing information about the logistics company.
  5. Dispatch.

What if a customer cancels the order after it has been dispatched! We will have to roll back all our transactions or update them with appropriate statuses. If we implement all the transactional behavior using a command pattern, life becomes a lot easier. Okay, I am really excited about how to implement the command pattern. Let’s look at it.

Implementation

Step 1- Define the command interface

First, we’ll create an interface to represent our command, that contains two methods — execute() and unexecute(). All the concrete classes will implement the respective behavior of the execute and un execution of the command.

Step 2 — Implement the Concrete commands.

We will define our logic of how to execute that command as well as how to unexecute it. For the understanding purpose, we are just inserting and deleting records from their respective table, but in the real world, it will surely contain more sophisticated logic.

Step 3 — Define Invoker

Invoker or client will be responsible to call the command’s execute() or unexecute() method. The invoker’s responsibility is similar to a waiter or remote control of our television that will be responsible for invoking commands given to it.

Let’s see the command pattern in action!

If we want to rollback our transactions then it’s pretty simple!

Another benefit of using the command pattern is that we can store all our commands in a list and execute them in-order. And if at some point in time an error or exception occurs, then it’s pretty simple to rollback. That’s the power of using the command pattern.

When to use it?

  1. After looking at the use case of the pattern, one thing we can surely derive is when we a have series of transactional behavior and there can be a possibility where we want to move back to the previous state that time this pattern can be a massively powerful tool.
  2. When the execution logic of the command is complex and used at multiple places in our application, then we can decouple it from the invoker and put it into a separate command. This will reduce the redundancy of our code and improve readability.

Okay! We’ve added the command pattern to our arsenal. Now let’s look at the definition of the pattern.

The command pattern encapsulates a request as an object, thereby letting us parameterize other objects with different requests, queue or log requests, and support undoable operations.

Thanks for reading.

Let’s meet in the next software design pattern! Till then Goodbye and Happy Learning!😃

--

--

Bhuvnesh Maheshwari
The Startup

Let’s be an awesome developer together! I will be learning the tech and sharing it with the community.