Menu
Coddy logo textTech

Patrón State

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

El patrón State permite que un objeto cambie su comportamiento cuando cambia su estado interno, haciendo que parezca que el objeto ha cambiado de clase. En lugar de usar condicionales complejos para gestionar diferentes estados, encapsulas cada estado en su propia clase y delegas el comportamiento al objeto de estado actual.

El patrón consta de un Contexto que mantiene una referencia al estado actual y de clases Estado que definen el comportamiento para cada estado posible. Cuando cambia el estado del contexto, su comportamiento cambia automáticamente:

abstract class DocumentState {
  void publish(Document doc);
  String getStatus();
}

class DraftState implements DocumentState {
  @override
  void publish(Document doc) {
    print('Moving to review...');
    doc.setState(ReviewState());
  }

  @override
  String getStatus() => 'Draft';
}

class ReviewState implements DocumentState {
  @override
  void publish(Document doc) {
    print('Document published!');
    doc.setState(PublishedState());
  }

  @override
  String getStatus() => 'Under Review';
}

class PublishedState implements DocumentState {
  @override
  void publish(Document doc) {
    print('Already published.');
  }

  @override
  String getStatus() => 'Published';
}

class Document {
  DocumentState _state = DraftState();

  void setState(DocumentState state) => _state = state;
  void publish() => _state.publish(this);
  String getStatus() => _state.getStatus();
}

void main() {
  var doc = Document();
  print(doc.getStatus());  // Borrador (Draft)
  doc.publish();           // Pasando a revisión... (Moving to review...)
  print(doc.getStatus());  // En revisión (Under Review)
  doc.publish();           // ¡Documento publicado! (Document published!)
  print(doc.getStatus());  // Publicado (Published)
}

Cada clase de estado maneja la acción publish() de manera diferente y puede realizar la transición del documento al siguiente estado. La clase Document no necesita condicionales para verificar su estado actual; simplemente delega en cualquier objeto de estado que esté activo en ese momento. Este patrón es ideal para objetos con distintos modos de comportamiento, como el procesamiento de pedidos, reproductores multimedia o sistemas de flujo de trabajo.

challenge icon

Desafío

Fácil

¡Construyamos un sistema de semáforo usando el patrón State! Crearás un semáforo que pasa por diferentes estados, donde cada estado determina el color de la luz y cómo transiciona al siguiente estado.

Organizarás tu código en dos archivos:

  • traffic_light.dart: Este archivo contiene tus clases de estado y el contexto del semáforo. Crea una clase abstracta TrafficLightState con dos métodos: String getColor(), que devuelve el color actual de la luz, y void next(TrafficLight light), que hace que el semáforo transicione a su siguiente estado. Implementa tres clases de estado concretas:
    • RedState: devuelve RED como su color e imprime Stop! Light is red. cuando se llama a next(); después, transiciona a GreenState
    • GreenState: devuelve GREEN como su color e imprime Go! Light is green. cuando se llama a next(); después, transiciona a YellowState
    • YellowState: devuelve YELLOW como su color e imprime Caution! Light is yellow. cuando se llama a next(); después, transiciona a RedState
    Después, crea una clase TrafficLight (el contexto) que comience en RedState. Debe tener un método setState() para cambiar el estado actual, un método getColor() que delegue en el estado actual y un método change() que llame a next() en el estado actual.
  • main.dart: Importa tu archivo del semáforo y demuestra el patrón State en acción. Crea un TrafficLight e imprime su color inicial. Después, llama a change() tres veces e imprime el color después de cada cambio. Esto mostrará cómo la luz pasa por todos los estados y vuelve al principio.

Observa que la clase TrafficLight no necesita condicionales para determinar el comportamiento: cada estado conoce su propio color y qué estado viene después. ¡El semáforo simplemente delega en el estado que está activo en ese momento!

Salida esperada:

RED
Stop! Light is red.
GREEN
Go! Light is green.
YELLOW
Caution! Light is yellow.
RED

Pruébalo tú mismo

import 'traffic_light.dart';

void main() {
  // TODO: Crear una instancia de TrafficLight
  
  // TODO: Imprimir el color inicial
  
  // TODO: Llamar a change() e imprimir el color (3 veces para recorrer todos los estados)
  // Primer cambio: RED -> GREEN
  
  // Segundo cambio: GREEN -> YELLOW
  
  // Tercer cambio: YELLOW -> RED
}
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