Command Pattern
Part of the Object Oriented Programming section of Coddy's Java journey — lesson 70 of 87.
The Command Pattern is a behavioral design pattern that turns a request into a stand-alone object containing all information about the request. This transformation lets you pass requests as method arguments, delay or queue a request's execution, and support undoable operations.
Think of it like a restaurant: instead of telling the chef directly what to cook, you write your order on a slip. The waiter (invoker) takes the slip (command) to the kitchen, where it can be queued, prioritized, or even cancelled. The pattern decouples the object that invokes the operation from the one that performs it.
The pattern has four key components: a Command interface declaring the execute method, ConcreteCommand classes that implement specific actions, a Receiver that performs the actual work, and an Invoker that triggers commands:
interface Command {
void execute();
}class Light { // Receiver
public void turnOn() {
System.out.println("Light is ON");
}
public void turnOff() {
System.out.println("Light is OFF");
}
}class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.turnOn();
}
}class RemoteControl { // Invoker
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}The invoker doesn't know what action will be performed—it just calls execute():
Light light = new Light();
Command lightOn = new LightOnCommand(light);
RemoteControl remote = new RemoteControl();
remote.setCommand(lightOn);
remote.pressButton(); // Output: Light is ONThe Command Pattern excels when you need to queue operations, implement undo/redo functionality, or schedule tasks for later execution. Each command encapsulates everything needed to perform an action, making your system more flexible and extensible.
Challenge
EasyLet's build a smart home automation system using the Command Pattern! You'll create a system where various home devices can be controlled through commands, allowing actions to be queued, executed, and even stored for later use—just like a universal remote control that doesn't need to know how each device works internally.
You'll organize your code across four files:
Command.java: Define theCommandinterface that all device commands will implement. It should declare a single methodexecute()that performs the command's action.Devices.java: Create two receiver classes that represent smart home devices:Television- has methodspowerOn()that printsTV is now ON,powerOff()that printsTV is now OFF, andsetChannel(int channel)that printsTV channel set to [channel].Thermostat- has methodssetTemperature(int temp)that printsThermostat set to [temp] degreesandturnOff()that printsThermostat turned OFF.Commands.java: Create concrete command classes that encapsulate device operations:TVOnCommand- takes aTelevisionin its constructor and callspowerOn()when executed.TVOffCommand- takes aTelevisionin its constructor and callspowerOff()when executed.TVChannelCommand- takes aTelevisionand anint channelin its constructor, and callssetChannel()with that channel when executed.ThermostatSetCommand- takes aThermostatand anint temperaturein its constructor, and callssetTemperature()with that value when executed.Main.java: Create aRemoteControlclass (the invoker) that has a methodsetCommand(Command cmd)to store a command andpressButton()to execute the stored command.In your main method, you'll receive two inputs: a TV channel number (integer) and a thermostat temperature (integer).
Create a
Televisionand aThermostat. Create aRemoteControland demonstrate the Command Pattern by:- Setting a
TVOnCommandand pressing the button - Setting a
TVChannelCommandwith your input channel and pressing the button - Setting a
ThermostatSetCommandwith your input temperature and pressing the button - Setting a
TVOffCommandand pressing the button
- Setting a
You will receive two inputs in order: the TV channel (integer) and the thermostat temperature (integer).
For example, with inputs 5 and 72, your output would be:
TV is now ON
TV channel set to 5
Thermostat set to 72 degrees
TV is now OFFNotice how the RemoteControl never directly interacts with the devices—it only knows about the Command interface. Each command encapsulates everything needed to perform its action, making it easy to add new devices and commands without changing the invoker!
Cheat sheet
The Command Pattern is a behavioral design pattern that encapsulates a request as an object, allowing you to parameterize clients with different requests, queue or log requests, and support undoable operations.
The pattern decouples the object that invokes the operation (invoker) from the one that performs it (receiver).
Key Components
- Command: Interface declaring the
execute()method - ConcreteCommand: Classes implementing specific actions
- Receiver: Object that performs the actual work
- Invoker: Object that triggers commands
Basic Structure
// Command interface
interface Command {
void execute();
}
// Receiver
class Light {
public void turnOn() {
System.out.println("Light is ON");
}
public void turnOff() {
System.out.println("Light is OFF");
}
}
// ConcreteCommand
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.turnOn();
}
}
// Invoker
class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}Usage
Light light = new Light();
Command lightOn = new LightOnCommand(light);
RemoteControl remote = new RemoteControl();
remote.setCommand(lightOn);
remote.pressButton(); // Output: Light is ONThe invoker doesn't know what action will be performed—it just calls execute(). This makes the system flexible and extensible, ideal for queuing operations, implementing undo/redo functionality, or scheduling tasks.
Try it yourself
import java.util.Scanner;
// TODO: Create RemoteControl class (the invoker) with:
// - setCommand(Command cmd) method to store a command
// - pressButton() method to execute the stored command
class RemoteControl {
// TODO: Implement RemoteControl
}
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Read inputs
int channel = scanner.nextInt();
int temperature = scanner.nextInt();
// TODO: Create a Television and a Thermostat
// TODO: Create a RemoteControl
// TODO: Demonstrate the Command Pattern:
// 1. Set a TVOnCommand and press the button
// 2. Set a TVChannelCommand with the input channel and press the button
// 3. Set a ThermostatSetCommand with the input temperature and press the button
// 4. Set a TVOffCommand and press the button
scanner.close();
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe this KeywordMethodsFields (Attributes)Constructor MethodConstructor OverloadingRecap - Simple Calculator4Inheritance
Basic Inheritance (extends)The super KeywordMethod Overriding (@Override)Constructor ChainingThe Object ClassSingle & Multilevel InheritWhy No Multi Class InheritRecap - Employee Hierarchy7Special Methods & Object Class
toString() Methodequals() and hashCode()clone() MethodcompareTo() and ComparableComparator InterfaceRecap - Custom Sorting2Access Modifiers & Encapsulate
Access Levels OverviewGetter and Setter MethodsInformation HidingThe final KeywordRecap - Bank Account Manager5Polymorphism
Method Overloading BasicsMethod Overriding (Run-Time)Upcasting and DowncastingThe instanceof OperatorAbstract Classes and MethodsRecap - Shape Calculator8Advanced OOP Concepts
Composition vs InheritanceAggregation vs CompositionInner Nested & Anonymous ClassEnums and Enum MethodsRecords (Java 16+)Sealed Classes (Java 17+)3Class Props & Static Member
Instance vs Static VariablesStatic MethodsStatic BlocksConstants (static final)Recap - Counter & Utility6Interfaces & Abstract Classes
Introduction to InterfacesImplementing InterfacesMulti Interface ImplemenDefault & Static in InterfaceAbstract Classes vs InterfacesFunctional InterfacesRecap - Payment System9Generics
Introduction to GenericsGeneric ClassesGeneric MethodsBounded Type ParametersWildcards (?, extends, super)Recap - Generic Container12Design Patterns Part 2
Command PatternAdapter PatternDecorator PatternTemplate Method PatternState PatternComposite PatternIterator Pattern