Lesson 4
Command Pattern
Command Pattern

Welcome to the lesson on the Command Pattern! This pattern is an essential part of Behavioral Design Patterns and focuses on encapsulating a request as an object. In this way, you can parameterize clients with different requests, queue them, log them, and even support undo operations. It's commonly used in scenarios where you need to decouple the object that invokes an operation from the object that performs it.

What You Will Learn

In this lesson, you will:

  • Understand the basics of the Command Pattern.
  • Learn how to implement this pattern in Java.
  • Recognize the significance of the Command Pattern in real-world applications.
Implementing the Command Pattern

The Command Pattern is a behavioral design pattern that turns a request into a stand-alone object that contains all the information about the request. This transformation allows you to parameterize methods with different requests, queue requests, and log their execution, among other things. At its core, it decouples the object that initiates an action from the object that performs the action.

Let's break down the implementation step-by-step using our example of a remote control for a light. We'll create commands to turn the light on and off, demonstrating the flexibility and reusability of the Command Pattern.

Step 1: Define the Command Interface
Java
1public interface Command { 2 void execute(); 3}

The Command interface defines a method called execute, which encapsulates an action. Any class implementing this interface must provide an implementation for the execute method.

Step 2: Implement the Receiver Class
Java
1public class Light { 2 public void on() { 3 System.out.println("Light is on."); 4 } 5 6 public void off() { 7 System.out.println("Light is off."); 8 } 9}

The Light class is our receiver. It contains the business logic to turn the light on or off.

Step 3: Implement Concrete Command for Turning the Light On
Java
1public class LightOnCommand implements Command { 2 private Light light; 3 4 public LightOnCommand(Light light) { 5 this.light = light; 6 } 7 8 @Override 9 public void execute() { 10 light.on(); 11 } 12}

The LightOnCommand class implements the Command interface. It has a reference to the Light object and calls its on method when execute is invoked.

Step 4: Implement Concrete Command for Turning the Light Off
Java
1public class LightOffCommand implements Command { 2 private Light light; 3 4 public LightOffCommand(Light light) { 5 this.light = light; 6 } 7 8 @Override 9 public void execute() { 10 light.off(); 11 } 12}

The LightOffCommand class also implements the Command interface. It has a reference to the Light object and calls its off method when execute is invoked.

Step 5: Implement the Invoker Class
Java
1public class RemoteControl { 2 private Command command; 3 4 public void setCommand(Command command) { 5 this.command = command; 6 } 7 8 public void pressButton() { 9 command.execute(); 10 } 11}

The RemoteControl class acts as the invoker. It holds a reference to a Command object and executes it when the button is pressed.

Step 6: Putting It All Together in the Main Class
Java
1public class Main { 2 public static void main(String[] args) { 3 Light light = new Light(); 4 Command lightOn = new LightOnCommand(light); 5 Command lightOff = new LightOffCommand(light); 6 7 RemoteControl remote = new RemoteControl(); 8 remote.setCommand(lightOn); 9 remote.pressButton(); // Outputs: Light is on. 10 remote.setCommand(lightOff); 11 remote.pressButton(); // Outputs: Light is off. 12 } 13}

In the Main class, we create the Light receiver, and the LightOnCommand and LightOffCommand concrete commands. We then create a RemoteControl invoker, set the commands, and execute them to see the results.

Why It Is Important

The Command Pattern is especially useful for:

  1. Decoupling: It decouples the object that requests an operation (invoker) from the one that actually performs the operation (receiver).
  2. Reusability: Commands can be reused and combined in complex scenarios, enhancing code maintainability and flexibility.
  3. History and Undo: It allows for adding history and undo features, crucial in applications like text editors, where users may want to revert actions.
  4. Logging: Commands can be logged, enabling actions to be recorded and replayed, useful for debugging and auditing purposes.

By the end of this lesson, you'll be more confident in applying the Command Pattern to your projects. Are you ready to practice and see this pattern in action? Let's move on to the practice section and enhance your coding skills!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.