Menu
Coddy logo textTech

Patrón Command

Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy. Lección 94 de 110.

El patrón Command encapsula una solicitud como un objeto, lo que te permite parametrizar los clientes con distintas solicitudes, poner operaciones en cola o admitir la funcionalidad de deshacer. En lugar de llamar directamente a un método, envuelves la acción en un objeto de comando que se puede almacenar, pasar de un lado a otro o ejecutar más tarde.

El patrón implica tres componentes clave: una interfaz Command con un método execute, Comandos concretos que implementan acciones específicas y un Receptor que realiza el trabajo real. Un Invocador opcional activa los comandos sin saber qué hacen:

abstract class Command {
  void execute();
}

class Light {
  void turnOn() => print('Light is ON');
  void turnOff() => print('Light is OFF');
}

class TurnOnCommand implements Command {
  final Light light;
  TurnOnCommand(this.light);

  @override
  void execute() => light.turnOn();
}

class TurnOffCommand implements Command {
  final Light light;
  TurnOffCommand(this.light);

  @override
  void execute() => light.turnOff();
}

class RemoteControl {
  Command? _command;

  void setCommand(Command command) {
    _command = command;
  }

  void pressButton() {
    _command?.execute();
  }
}

void main() {
  var light = Light();
  var remote = RemoteControl();

  remote.setCommand(TurnOnCommand(light));
  remote.pressButton();  // La luz está ENCENDIDA

  remote.setCommand(TurnOffCommand(light));
  remote.pressButton();  // La luz está APAGADA
}

El RemoteControl no sabe nada sobre las luces; simplemente ejecuta cualquier comando que se le asigne. Este desacoplamiento facilita añadir nuevos comandos sin modificar el invocador. El patrón Command es ideal para implementar sistemas de deshacer/rehacer, colas de tareas o grabación de macros cuando necesitas tratar las acciones como objetos de primera clase.

challenge icon

Desafío

Fácil

¡Construyamos un sistema de comandos para un editor de texto usando el patrón Command! Crearás un sistema que encapsula las operaciones de texto como objetos de comando, lo que permite que un editor ejecute diferentes acciones sin conocer los detalles de cada operación. Este es un caso de uso clásico del patrón Command: piensa en él como un sistema de deshacer/rehacer en el que cada acción se almacena como un objeto.

Organizarás tu código en dos archivos:

  • commands.dart: Crea aquí tu sistema de comandos. Comienza con una clase abstracta Command que declare un método execute(). Después, crea una clase TextDocument (el receptor) que contenga un campo String content (inicialmente vacío) y tenga tres métodos:
    • append(String text): añade texto al final del contenido
    • clear(): establece el contenido como una cadena vacía
    • show(): imprime Document: [content]
    Ahora implementa tres comandos concretos que funcionen con un TextDocument:
    • AppendCommand: recibe un documento y texto en su constructor, y añade el texto cuando se ejecuta
    • ClearCommand: recibe un documento en su constructor y lo borra cuando se ejecuta
    • ShowCommand: recibe un documento en su constructor y muestra su contenido cuando se ejecuta
    Finalmente, crea una clase TextEditor (el invocador) que almacene una lista de comandos. Debe tener un método addCommand(Command command) para poner comandos en cola, y un método runAll() que ejecute todos los comandos en cola en orden.
  • main.dart: Importa tu archivo de comandos y demuestra el patrón Command. Crea un TextDocument y un TextEditor. Pon en cola los siguientes comandos en orden: añadir Hello, añadir World, mostrar el documento, añadir !, mostrarlo de nuevo, borrar el documento y mostrarlo una última vez. Después, ejecuta todos los comandos en cola.

Observa que TextEditor no sabe nada sobre añadir, borrar o mostrar; simplemente ejecuta los comandos que recibe. ¡Este desacoplamiento es la esencia del patrón Command!

Salida esperada:

Document: Hello World
Document: Hello World!
Document: 

Pruébalo tú mismo

import 'commands.dart';

void main() {
  // TODO: Crear una instancia de TextDocument

  // TODO: Crear una instancia de TextEditor

  // TODO: Poner en cola los siguientes comandos en orden:
  // 1. Añadir "Hello"
  // 2. Añadir " World"
  // 3. Mostrar el documento
  // 4. Añadir "!"
  // 5. Mostrar el documento de nuevo
  // 6. Limpiar el documento
  // 7. Mostrar el documento una última vez

  // TODO: Ejecutar todos los comandos en cola
}
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 Dart online