The command design pattern is one of the behavioral design patterns. This design pattern can be considered for use when there is clear segregation between requester and executor of an action or a command.
In the command design pattern, all information needed to perform an action are encapsulated in an object. This information includes following things:
- The method name
- The object that owns the method
- Values for the method parameters
Following terms always comes with command pattern i.e. Command, Concrete Command, Receiver, Invoker, and Client.
xHere are ALL other Java Design Patterns, explained in detail with examplesx
Command
This declares a common interface that will be implemented by all Concrete Commands. At a minimum, it must declare one method to execute the actual action.
Concrete Command
This class performs actual operation or command. It extends the Command interface and implements the appropriate method for execution on a receiver.
Client
The client has the responsibility to create Concrete Command. The command then passed on to Invoker.
Invoker
As the name suggests, these are only to invoke actual execute operation or action. These classes get a pre-created concrete commands object from the client.
Receiver
These hold the business logic to carry out a command or operation.
The command design pattern can be explained perfectly with a restaurant example. Where the customer places an order/command with the waiter. Then waiter runs it through his manager and then its passed on to cook for execution. When food is ready, the command to serve food to the customer is carried out by the waiter.
Let us see this pattern with code:
To start we will have our core the command interface:
//Command Interface public interface Command { public void execute(); }
For our example, the receiver would be actual Order object. As all the commands will be executed on that.
//Receiver public class Order { private String foodItem; private Integer foodQuantity; private boolean orderPlaced; private boolean orderValidated; private boolean orderPrepared; private boolean orderServed; //Getters //Setters }
We have added few booleans to our receiver so we can track the commands executed.
Waiter, Manager, and Cooks will be our invokers. So we have simple class structure for them
public abstract class Invoker { //Name of Waiter, Manager etc private String name; //Command to invoke private Command command; public abstract void invokeCommand(); }
The Waiter
//Invoker public class Waiter extends Invoker { @Override public void invokeCommand() { this.getCommand().execute(); } public void takeOrder() { invokeCommand(); } public void serveOrder() { invokeCommand(); } }
Similarly, we have classes for Manager and Cook.
Now letxs see the actual concrete command
//Concrete Command public class CommandPlaceOrder implements Command { private Order order; public CommandPlaceOrder(Order order) { this.order = order; } @Override public void execute() { this.order.setOrderPlaced(true); System.out.println(this.order); } }
Above is a concrete command which will be taken by the waiter and executed on object Order. Similar concrete commands are prepared for validating orders, cooking and serving the order.
Lastly, lets define the client now.
//Client public class ClientCustomer { public ClientCustomer() { Order myOrder = new Order("Veg Burger", 2); //Place Order CommandPlaceOrder cmdPlaceOrder = new CommandPlaceOrder(myOrder); Waiter waiter = new Waiter(); waiter.setCommand(cmdPlaceOrder); waiter.takeOrder(); //Validate Order CommandValidateOrder cmdValidateOrder = new CommandValidateOrder(myOrder); Manager manager = new Manager(); manager.setCommand(cmdValidateOrder); manager.validateOrder(); CommandCookOrder cmdCookOrder = new CommandCookOrder(myOrder); Cook cook = new Cook(); cook.setCommand(cmdCookOrder); cook.prepareOrder(); CommandServeOrder cmdServeOrder = new CommandServeOrder(myOrder); waiter.setCommand(cmdServeOrder); waiter.serveOrder(); } }
From above its pretty clear how the client prepares and Order and gives the command to the waiter. The class also takes you through how the other commands are carried out by Manager and Cook.
When you run this program, you will see state or Order object after each command. Here is the output:
Order [ Veg Burger, 2 Placed : true Validated : false Prepared : false Served : false ] Order [ Veg Burger, 2 Placed : true Validated : true Prepared : false Served : false ] Order [ Veg Burger, 2 Placed : true Validated : true Prepared : true Served : false ] Order [ Veg Burger, 2 Placed : true Validated : true Prepared : true Served : true ]
Advantages
- Using command pattern you can create a sequence of commands.
- Adding a new command is easy and for addition no need to change the existing code.
- Command pattern decouples the object that invokes the operation from the one that knows how to perform it.
Disadvantages
- There are many classes and objects working together to achieve a goal. Application developers need to be careful while developing these classes correctly.
- Every individual command is a Concrete Command class which will be difficult for implementation and maintenance.
Conclusion
The article gives clear idea of what Command Design Pattern is and how it can be leveraged.
You can download the code from our GitHub repository:
Download from Gitx
xHere are ALL other Java Design Patterns, explained in detail with examplesx