Command Design Pattern In Java
Join the DZone community and get the full member experience.Join For Free
Today, I am here to discuss another behavioral design pattern called Command Design Pattern. A very useful pattern in which we wrap the request in an object known as Command and provide it an Invoker to perform.
Command Design Pattern
- In the Command Design Pattern, we wrap our requests in a Command object, along with all the required information to perform an action of another object.
- The Command object knows about the Receiver and invokes methods of the receiver by supplying parameters. Values for parameters of the receiver methods are stored in the Command object.
- The Receiver objects performs the job when the
execute()method of Command gets called.
- We pass this Command object to an Invoker object to perform the execute method. Invoker object executes the methods of the Command object and passes the required parameters to it.
- The Invoker objects knows how to execute the command. But, it does not know anything about any concrete command. All it knows about is the command interface/abstract class.
- The Invoker can take different Command objects time-to-time, so the Client deals only with the Invoker to perform operations on different objects. These objects call Receiver objects.
- The Command object collects all the details of requests and performs operations on the Receiver.
- The Command Design Pattern supports undoable operations as well and we can have an unexecute kind of method to return the state of the object back to its original state.
- So, the pattern makes it super easy to perform a verity of jobs/requests in a simple way by using Invoker object.
- The Invoker may also do bookkeeping for the Command objcets.
- Different Command object may have different Receiver object to act on.
- The execute method defines and performs all the operations in the sequence to complete the job.
- The Client Application knows when and in which order to execute the commands.
- The only drawback of this pattern is we end up creating many command classes.
So, as you can see that in the above diagram, we wrap the request in a Command object.
Take Command1 for some request. We give all the parameter values required by the Receiver object to perform the request into Command1. Then, we set this command to Invoker and Invoker triggers the command. Command1's execute method comes into the action and performs all the operations required on Receiver object in a define order. Client gets the output via Receiver. That's it! in simple words.
Now an example to explain it.
Home Automation Application using Command Design Pattern
Suppose we like to control our home appliances with the help of a Smart Remote. The Home Appliances will act as receiver here. Smart Remote will act as an invoker. Operations on the appliances will be concrete commands and Client will be our main application.
To make it little user-friendly, I am trying here to provide command as statement like
'turn on bedroomlight' or 'bedroomlight switch off'
Sounds interesting? Well its not that much difficult. All I am trying here is make it super easy and without using any third party libraries; only based on Java 8 (mainly lambda's).
I think you guess it write, we need keywords and a command interpreter which will help us to find the right command and home appliance to select and perform the operation.
So without wasting more time, here's the code.
Code for Appliance class:
I have defined common operations like 'On' and 'Off' here.
Code for Fan class:
I have added operations like 'Increase' and 'Decrease' here and its a sub-type of Appliance.
Code for Light class:
No additional operations are needed since we already have 'On' and 'Off' defined.
Code for TV class:
I have added operations like 'Increase/Decrease Volume', 'Increase/Decrease Channel' and 'Sound Mute'.
Now lets create some classes to create actual home appliance objects. I am creating them as separate classes because bed-room-light need not to be same as kitchen light and may have some additional operations like setting color white or warm white or even multi-color. I am not adding that level of piece of code and encourage you to think on that. Also, you may enhance it for real IoT project using some controllers with raspberry pi or something similar and control your home appliances. Please search on the Net for more information. Also if you need, I can provide additional information on that.
Code for BedRoomFan class:
Code for BedRoomLight class:
Code for KitchenLight class:
Code for Microwave class:
Code for LivingRoomFan class:
Code for LivingRoomLight class:
Code for LivingRoomTV class:
Now, when all the appliances are defined along with their operations, it's time to work on Command Design Pattern. The above appliance-classes will be our Receiver objects.
Code for Command abstract class.
Please note that I have provided additional methods like 'keywords'. This will help us while interpreting the command.
Now, the code for concrete command classes. Just to avoid creating many class files, I wrote them as as a public static nested classes inside a public class called Commands.
Code for Commands class:
Please notice that I also provided keywords along with the concrete-commands to decode them correctly. I am using interpreter here to identifying the appliance and the command to perform. I will try to write another article on Interpreters to make this more clear for the audience.
Code for CommandInterpreter class :
This class receives the provided command string and perform keyword searching to identify the right command and appliance to perform the right action.
Code for HomeAutomation class:
I wrote this class as a Home Automation Hub (singleton). You can read more on in my article on Singleton Design Pattern.
Code for HomeRemote class:
This HomeRemote will act as Invoker for us.
Now it's time to write Main program to execute and test output.
Below is the command to run this code post mvn build.
And here's the output:
Source Code can be found here: Command-Design-Pattern-Sample-Code
I hope this tutorial demonstrates the use of command design pattern.
Liked the article? Please don't forget to press that like button. Happy coding!
Need more articles, please visit my profile: Brijesh Saxena.
Opinions expressed by DZone contributors are their own.