The command pattern comes under behavioral patterns. In object-oriented programming, we use command pattern for mainly to decouple the object that sends a request from the object that knows how to execute it. In the command pattern, an object is used to encase all chunks of the information, which is required to perform or execute a request, the details are saved in the object, for later, when the request is needed to be executed.
According to the Gang of Four:
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
The details may include, values for the method parameters, method name and the object that actually owns this method. The four most commonly used terms in the command pattern include receiver, invoker, command and client. The command object contains the information of the receiver and generates method of the receiver.
The command object also stores the parameter values of the method of the receiver and the receiver object that is to execute the methods by aggregation. When the execute() method in the command object is called, the receiver object does its work. The invoker object is the one that knows how to execute the request or command, and it also keeps the records about the command execution. The invoker object does not have any information about the concrete command, it is only allowed to know about the command interface. The client object holds the rest of the three objects- invoker object, command object, receiver object.
also read:
The decision about which receiver objects are assigned to which command objects or which command object is assigned to which invoker object, is concluded by the client object. The executions of which commands and at which points, is also decided by the client object. In order to execute a command, the client object passes the command object to the invoker object.
It becomes easier to generate the general components that need to assign, sequence or carry out method calls at their required time, without having to know the class of the method or the parameters of the method. The invoker object keeps a record of the executed commands, which allows the command to be executed conveniently. It also allows to implement various modes of commands, these modes are managed by the invoker object, without having the client be aware of the modes or the existence of the records.
To design, versatile and reusable object-oriented software, there are 23 well-known design patterns, the command pattern is one of them. The design of the command pattern is such that the client that requests a command is different than the one that executes it. This decoupling helps to bend, which in turn helps in the timing and the sequencing of the commands. The command objects are materialized in an object so that they are allowed to be passed, staged, shared as per requirement or else manipulated like any other object.
There are some problems that are catered by the command pattern. The system needs to avoid the coupling of the invoker object, which requests a command, with that particular command. With the help of the generated request, the invoker object (generator of that request), can be configured.
Let’s see the following diagram about this command pattern and it’s components classes.
It is an interface or abstract class has action to perform in the system.
It is a concrete implementation of the Command interface and defining an action will be performed.
This is main class, it creates a ConcreteCommand object and sets its receiver.
It is a caller to invoke the request to carry the command object.
It is simple handler method which perform the actual operation by ConcreteCommand.
The following lists the benefits of using the Command Pattern:
We have created an interface Command which is acting as a command. And also created an Account class which acts as a request. Here I concrete command classes OpenAccount and CloseAccount implementing Command interface which will do actual command processing. A class Bank is created which acts as an invoker object. It can take and execute the commands.
Bank object uses command pattern to identify which object will execute which command based on the type of command. CommandPatternDemo, our demo class, will use Bank class to demonstrate command pattern.
/** * */ package com.doj.patterns.behavior.command; /** * @author Dinesh.Rajput * */ public interface Command { void execute(); }
/** * */ package com.doj.patterns.behavior.command; /** * @author Dinesh.Rajput * */ public class Account { private String name = "Dinesh"; private int balance = 1000; public void open(){ System.out.println("Account [ Name: "+name+", Balance: " + balance +" ] Opened"); } public void close(){ System.out.println("Account [ Name: "+name+", Balance: " + balance +" ] closed"); } }
package com.doj.patterns.behavior.command; /** * @author Dinesh.Rajput * */ public class OpenAccount implements Command { private Account account; public OpenAccount(Account account){ this.account = account; } @Override public void execute() { account.open(); } }
/** * */ package com.doj.patterns.behavior.command; /** * @author Dinesh.Rajput * */ public class CloseAccount implements Command { private Account account; public CloseAccount(Account account){ this.account = account; } @Override public void execute() { account.close(); } }
/** * */ package com.doj.patterns.behavior.command; import java.util.ArrayList; import java.util.List; /** * @author Dinesh.Rajput * */ public class Bank { private ListcommandList = new ArrayList (); public void takeCommand(Command command){ commandList.add(command); } public void executeCommands(){ for (Command command : commandList) { command.execute(); } commandList.clear(); } }
/** * */ package com.doj.patterns.behavior.command; /** * @author Dinesh.Rajput * */ public class CommandPatternDemo { /** * @param args */ public static void main(String[] args) { Account account = new Account(); OpenAccount openAccount = new OpenAccount(account); CloseAccount closeAccount = new CloseAccount(account); Bank bank = new Bank(); bank.takeCommand(openAccount); bank.takeCommand(closeAccount); bank.executeCommands(); } }
Account [ Name: Dinesh, Balance: 1000 ] Opened Account [ Name: Dinesh, Balance: 1000 ] closed
Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…
Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…
Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…
Technology has emerged a lot in the last decade, and now we have artificial intelligence;…
Managing a database is becoming increasingly complex now due to the vast amount of data…
Overview In this article, we will explore Spring Scheduler how we could use it by…