Menu
Coddy logo textTech

Patrón Command

Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy. Lección 70 de 87.

El patrón Command es un patrón de diseño de comportamiento que convierte una solicitud en un objeto independiente que contiene toda la información sobre la solicitud. Esta transformación te permite pasar solicitudes como argumentos de métodos, retrasar o poner en cola la ejecución de una solicitud y admitir operaciones que se pueden deshacer.

Piensa en ello como en un restaurante: en lugar de decirle directamente al chef qué cocinar, escribes tu pedido en una comanda. El camarero (invocador) lleva la comanda (comando) a la cocina, donde puede ponerse en cola, priorizarse o incluso cancelarse. El patrón desacopla el objeto que invoca la operación del que la ejecuta.

El patrón tiene cuatro componentes clave: una interfaz Command que declara el método execute, clases ConcreteCommand que implementan acciones específicas, un Receiver que realiza el trabajo real y un Invoker que activa los comandos:

interface Command {
    void execute();
}
class Light {  // Receptor
    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 {  // Invocador
    private Command command;
    
    public void setCommand(Command command) {
        this.command = command;
    }
    
    public void pressButton() {
        command.execute();
    }
}

El invocador no sabe qué acción se realizará. Simplemente llama a execute():

Light light = new Light();
Command lightOn = new LightOnCommand(light);

RemoteControl remote = new RemoteControl();
remote.setCommand(lightOn);
remote.pressButton();  // Salida: Light is ON

El patrón Command es excelente cuando necesitas poner operaciones en cola, implementar la funcionalidad de deshacer/rehacer o programar tareas para ejecutarlas más adelante. Cada comando encapsula todo lo necesario para realizar una acción, lo que hace que tu sistema sea más flexible y extensible.

challenge icon

Desafío

Fácil

¡Construyamos un sistema de automatización inteligente del hogar usando el patrón Command! Crearás un sistema en el que varios dispositivos del hogar se pueden controlar mediante comandos, lo que permite poner acciones en cola, ejecutarlas e incluso almacenarlas para usarlas más adelante, como un control remoto universal que no necesita saber cómo funciona internamente cada dispositivo.

Organizarás tu código en cuatro archivos:

  • Command.java: Define la interfaz Command que implementarán todos los comandos de los dispositivos. Debe declarar un único método execute() que realice la acción del comando.
  • Devices.java: Crea dos clases receptoras que representen dispositivos inteligentes del hogar:

    Television: tiene métodos powerOn() que imprime TV is now ON, powerOff() que imprime TV is now OFF y setChannel(int channel) que imprime TV channel set to [channel].

    Thermostat: tiene métodos setTemperature(int temp) que imprime Thermostat set to [temp] degrees y turnOff() que imprime Thermostat turned OFF.

  • Commands.java: Crea clases de comandos concretos que encapsulen las operaciones de los dispositivos:

    TVOnCommand: recibe un Television en su constructor y llama a powerOn() cuando se ejecuta.

    TVOffCommand: recibe un Television en su constructor y llama a powerOff() cuando se ejecuta.

    TVChannelCommand: recibe un Television y un int channel en su constructor, y llama a setChannel() con ese canal cuando se ejecuta.

    ThermostatSetCommand: recibe un Thermostat y un int temperature en su constructor, y llama a setTemperature() con ese valor cuando se ejecuta.

  • Main.java: Crea una clase RemoteControl (el invocador) que tenga un método setCommand(Command cmd) para almacenar un comando y pressButton() para ejecutar el comando almacenado.

    En tu método main, recibirás dos entradas: un número de canal de TV (entero) y una temperatura del termostato (entero).

    Crea un Television y un Thermostat. Crea un RemoteControl y demuestra el patrón Command de la siguiente manera:

    1. Establece un TVOnCommand y presiona el botón
    2. Establece un TVChannelCommand con el canal introducido y presiona el botón
    3. Establece un ThermostatSetCommand con la temperatura introducida y presiona el botón
    4. Establece un TVOffCommand y presiona el botón

Recibirás dos entradas en orden: el canal de TV (entero) y la temperatura del termostato (entero).

Por ejemplo, con las entradas 5 y 72, tu salida sería:

TV is now ON
TV channel set to 5
Thermostat set to 72 degrees
TV is now OFF

Observa que RemoteControl nunca interactúa directamente con los dispositivos. Solo conoce la interfaz Command. Cada comando encapsula todo lo necesario para realizar su acción, lo que facilita agregar nuevos dispositivos y comandos sin cambiar el invocador.

Pruébalo tú mismo

import java.util.Scanner;

// TODO: Crea la clase RemoteControl (el invocador) con:
// - método setCommand(Command cmd) para almacenar un comando
// - método pressButton() para ejecutar el comando almacenado

class RemoteControl {
    // TODO: Implementa RemoteControl
}

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Lee las entradas
        int channel = scanner.nextInt();
        int temperature = scanner.nextInt();
        
        // TODO: Crea un Television y un Thermostat
        
        // TODO: Crea un RemoteControl
        
        // TODO: Demuestra el patrón Command:
        // 1. Establece un TVOnCommand y presiona el botón
        // 2. Establece un TVChannelCommand con el canal de entrada y presiona el botón
        // 3. Set a ThermostatSetCommand with the input temperature and press the button
        // 4. Establece un TVOffCommand y presiona el botón
        
        scanner.close();
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Java online