The Command Pattern consists of four main components:
execute()
method. Concrete command classes implement this method to define the specific action to be performed.Command
interface. Each concrete command class encapsulates a receiver and a set of actions to be performed on that receiver.execute()
method.The main idea behind the Command Pattern is to separate the responsibility of issuing a request from the object that will handle the request. This separation allows for greater flexibility and extensibility in the codebase.
// Command interface
interface Command {
void execute();
}
// Receiver class
class Light {
public void turnOn() {
System.out.println("Light is on");
}
public void turnOff() {
System.out.println("Light is off");
}
}
// Concrete command classes
class TurnOnLightCommand implements Command {
private Light light;
public TurnOnLightCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
}
class TurnOffLightCommand implements Command {
private Light light;
public TurnOffLightCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
}
// Invoker class
class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
public class Main {
public static void main(String[] args) {
Light light = new Light();
Command turnOnCommand = new TurnOnLightCommand(light);
Command turnOffCommand = new TurnOffLightCommand(light);
RemoteControl remoteControl = new RemoteControl();
// Turn on the light
remoteControl.setCommand(turnOnCommand);
remoteControl.pressButton();
// Turn off the light
remoteControl.setCommand(turnOffCommand);
remoteControl.pressButton();
}
}
import java.util.LinkedList;
import java.util.Queue;
public class CommandQueue {
private Queue<Command> queue = new LinkedList<>();
public void addCommand(Command command) {
queue.add(command);
}
public void executeCommands() {
while (!queue.isEmpty()) {
queue.poll().execute();
}
}
}
import java.util.logging.Level;
import java.util.logging.Logger;
class LoggingCommand implements Command {
private static final Logger LOGGER = Logger.getLogger(LoggingCommand.class.getName());
private Command command;
public LoggingCommand(Command command) {
this.command = command;
}
@Override
public void execute() {
LOGGER.log(Level.INFO, "Executing command: " + command.getClass().getSimpleName());
command.execute();
}
}
undo()
method to the Command
interface and implement it in the concrete command classes.The Command Pattern is a powerful design pattern that can simplify your Java codebase by decoupling the sender of a request from the receiver. It provides a way to encapsulate a request as an object, which allows for greater flexibility and extensibility. By following the common practices and best practices outlined in this blog, you can effectively use the Command Pattern in your Java applications.