The Command pattern is known as a behavioral pattern, as it's used to manage algorithms, relationships and responsibilities between objects. The Command pattern transforms a set of related algorithms into a type, instances of which encapsulate all the logic and data required to perform a particular algorithm.
1. Command pattern in Java
The Command pattern is known as a behavioral pattern, as it's used to manage
algorithms, relationships and responsibilities between objects. The Command
pattern transforms a set of related algorithms into a type, instances of which
encapsulate all the logic and data required to perform a particular algorithm.
Purpose of Command pattern
Design patterns not only accelerate the design phase of an object-oriented (OO) project
but also increase the productivity of the development team and quality of the software.
A Command pattern is an object behavioral pattern that allows us to achieve complete
decoupling between the sender and the receiver.
A sender is an object that invokes an operation, and a receiver is an object that receives
the request to execute a certain operation. With decoupling, the sender has no knowledge
of the Receiver's interface.
The term request here refers to the command that is to be executed. The Command
pattern also allows us to vary when and how a request is fulfilled. Therefore, a Command
pattern provides us flexibility as well as extensibility.
Scope of Command pattern
The most common use of the Command pattern is to execute, undo and redo actions. But
commands can be asked to perform other tasks as well.
Using the Command pattern, the Invoker that issues a request on behalf of the client and
the set of service-rendering Receiver objects can be decoupled.
The Command pattern suggests creating an abstraction for the processing to be carried
out or the action to be taken in response to client requests.
This abstraction can be designed to declare a common interface to be implemented by
different concrete implementers referred to as Command objects.
Each Command object represents a different type of client request and the corresponding
processing.
A given Command object is responsible for offering the functionality required to process
the request it represents, but it does not contain the actual implementation of the
functionality.
2. Intent of Command pattern
o encapsulate a request in an object .
o allows the parameterization of clients with different requests.
o allows saving the requests in a queue.
o An object-oriented callback.
Name and Classification
Design patterns not only accelerate the design phase of an object-oriented project but also
increase the productivity of the development team and quality of the software. A
Command pattern is an object behavioral pattern that allows us to achieve complete
decoupling between the sender and the receiver. A sender is an object that invokes an
operation, and a receiver is an object that receives the request to execute a certain
operation. With decoupling, the sender has no knowledge of the Receiver's inter.
Problem and Solution for Command pattern
The Command Pattern is useful when:
A history of requests is needed .
We need callback functionality.
Requests need to be handled at variant times or in variant orders.
The invoker should be decoupled from the object handling the invocation.
Coupling the invoker of a request to a particular request should be avoided.
It should be possible to configure an object with a request.
Consequences
Pros:
decouples the object that invokes the operation from the one that know how
to perform it.
This pattern helps in terms of extensible as we can add a new command
without changing the existing code.
It allows you to create a sequence of commands named macro. To run the
macro, create a list of Command instances and call the execute method of
all commands.
Ability to undo/redo easily.
Cons:
increase in the number of classes for each individual command.
There are a high number of classes and objects working together to achieve a goal.
3. Structure
Fig: Object Behavioral Command pattern
Command declares an interface for all commands, providing a simple execute() method
which asks the Receiver of the command to carry out an operation. The Receiver has the
knowledge of what to do to carry out the request. The Invoker holds a command and can
get the Command to execute a request by calling the execute method. The Client creates
ConcreteCommands and sets a Receiver for the command. The ConcreteCommand
defines a binding between the action and the receiver. When the Invoker calls execute the
ConcreteCommand will run one or more actions on the Receiver.
The following sequence diagram shows the relationship in a clearer way:
4. Command Pattern: participants
Command:– Declares an interface for executing an operation.
ConcreteCommand :– Implements execute( ) by invoking the corresponding operation(s)
on Receiver(s).
Client:– Creates a ConcreteCommand object and sets its Receiver.
Invoker: – Asks its Command to carry out the request.
Receiver:– Any classes that know how to perform the operation(s) associated with
carrying out a request.
Collaborations
The client creates a ConcreteCommand object and specifies its receiver.
An Invoker object stores the ConcreteCommand object.
The invoker issues a request by calling Execute on the command. When
commands are undoable, ConcreteCommand stores state for undoing the
command prior to invoking Execute.
The ConcreteCommand object invokes operations on its receiver to carry out the
request
Command pattern example code
Let's use a switch control as the example. Our switch is the center of home automation
and can control everything. We'll just use a light as an example, that we can switch on or
off, but we could add many more commands:
o First we'll create our command interface:
//Command
public interface Command{
public void execute();
}
o Now let's create two concrete commands. One will turn on the lights, another
turns off lights:
//Concrete Command
public class LightOnCommand implements Command{
//reference to the light
Light light;
public LightOnCommand(Light light){
this.light = light;
5. }
public void execute(){
light.switchOn();
}
}
//Concrete Command
public class LightOffCommand implements Command{
//reference to the light
Light light;
public LightOffCommand(Light light){
this.light = light;
}
public void execute(){
light.switchOff();
}
}
o Light is our receiver class, so let's set that up now:
//Receiver
public class Light{
private boolean on;
public void switchOn(){
on = true;
}
public void switchOff(){
on = false;
}
}
o Our invoker in this case is the remote control
//Invoker
public class RemoteControl{
private Command command;
public void setCommand(Command command){
this.command = command;
}
public void pressButton(){
command.execute();
}
}
o Finally we'll set up a client to use the invoker
//Client
public class Client{
public static void main(String[] args) {
RemoteControl control = new RemoteControl();
6. Light light = new Light();
Command lightsOn = new LightsOnCommand(light);
Command lightsOff = new LightsOffCommand(light);
//switch on
control.setCommand(lightsOn);
control.pressButton();
//switch off
control.setCommand(lightsOff);
control.pressButton();
}
}
The Uses of Command Pattern in real System
Graphic User Interface (GUI): In GUI and menu items, we use command pattern.
By clicking a button we can read the current information of GUI and take an
action.
Macro Recording: If each of user action is implemented as a separate Command,
we can record all the user actions in a Macro as a series of Commands. We can use
this series to implement the “Playback” feature. In this way, Macro can keep on
doing same set of actions with each replay.
Multi-step Undo: When each step is recorded as a Command, we can use it to
implement Undo feature in which each step can by undo. It is used in text editors
like MS-Word.
Networking: We can also send a complete Command over the network to a remote
machine where all the actions encapsulated within a Command are executed.
Progress Bar: We can implement an installation routine as a series of Commands.
Each Command provides the estimate time. When we execute the installation
routine, with each command we can display the progress bar.
Transactions: In a transactional behavior code there are multiple tasks/updates.
When all the tasks are done then only transaction is committed. Else we have to
rollback the transaction. In such a scenario each step is implemented as separate
Command.