Menu
Coddy logo textTech

Patrón State

Parte de la sección Programación Orientada a Objetos del Journey de C# de Coddy. Lección 60 de 70.

El patrón State es un patrón de comportamiento que permite que un objeto cambie su comportamiento cuando cambia su estado interno. En lugar de usar instrucciones condicionales complejas 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 tres componentes: una interfaz de estado que define el comportamiento específico del estado, clases de estado concretas que implementan dicho comportamiento y una clase de contexto que mantiene una referencia al estado actual:

public interface IDocumentState
{
    void Publish(Document doc);
}

public class DraftState : IDocumentState
{
    public void Publish(Document doc)
    {
        Console.WriteLine("Moving to moderation");
        doc.SetState(new ModerationState());
    }
}

public class ModerationState : IDocumentState
{
    public void Publish(Document doc)
    {
        Console.WriteLine("Publishing document");
        doc.SetState(new PublishedState());
    }
}

public class PublishedState : IDocumentState
{
    public void Publish(Document doc)
    {
        Console.WriteLine("Already published");
    }
}

El contexto mantiene el estado actual y le delega las acciones. Los objetos de estado pueden activar transiciones llamando a SetState() en el contexto:

public class Document
{
    private IDocumentState _state = new DraftState();
    
    public void SetState(IDocumentState state) => _state = state;
    
    public void Publish() => _state.Publish(this);
}

var doc = new Document();
doc.Publish();  // Pasando a moderación
doc.Publish();  // Publicando documento
doc.Publish();  // Ya publicado

El patrón State elimina las extensas instrucciones if-else o switch que comprueban el estado actual. Cada clase de estado gestiona únicamente su propio comportamiento, lo que facilita el mantenimiento del código y su ampliación con nuevos estados.

challenge icon

Desafío

Fácil

Construyamos un sistema de semáforo usando el patrón State. Los semáforos pasan por estados distintos (rojo, amarillo, verde), y cada estado determina qué ocurre cuando cambia la luz. En lugar de usar condicionales complejas, encapsularás cada estado de la luz en su propia clase.

Organizarás tu código en tres archivos:

  • TrafficLightState.cs: Define una interfaz ITrafficLightState en el espacio de nombres Traffic con un método Change(TrafficLight light). Después crea tres clases de estado concretas:
    • RedState: cuando se llama a Change, imprime Red - Stop! Changing to Green... y cambia la luz a GreenState
    • GreenState: imprime Green - Go! Changing to Yellow... y cambia a YellowState
    • YellowState: imprime Yellow - Caution! Changing to Red... y cambia a RedState
  • TrafficLight.cs: Crea una clase TrafficLight en el mismo espacio de nombres. Esta es tu clase de contexto, que mantiene el estado actual. Debe comenzar en RedState de forma predeterminada y tener:
    • Un método SetState(ITrafficLightState state) que los objetos de estado usan para activar las transiciones
    • Un método Change() que delega en el método Change del estado actual
  • Program.cs: Une todo creando un TrafficLight y recorriendo los cambios de estado según la entrada.

Recibirás una entrada:

  • El número de veces que se debe cambiar el semáforo (un entero)

Crea un TrafficLight (que comienza en rojo) y llama a Change() el número de veces especificado.

Por ejemplo, si la entrada es 3, la salida debe ser:

Red - Stop! Changing to Green...
Green - Go! Changing to Yellow...
Yellow - Caution! Changing to Red...

Si la entrada es 5, la luz vuelve a recorrer el ciclo:

Red - Stop! Changing to Green...
Green - Go! Changing to Yellow...
Yellow - Caution! Changing to Red...
Red - Stop! Changing to Green...
Green - Go! Changing to Yellow...

Observa que la clase TrafficLight no contiene lógica sobre lo que significa cada color ni sobre cuál viene después; todo ese conocimiento reside en las clases de estado individuales. Cada estado es responsable de su propio comportamiento y de activar la transición al siguiente estado.

Pruébalo tú mismo

using System;
using Traffic;

class Program
{
    public static void Main(String[] args)
    {
        // Lee el número de veces que se debe cambiar el semáforo
        int n = Convert.ToInt32(Console.ReadLine());

        // TODO: Crea una instancia de TrafficLight (comienza en RedState por defecto)

        // TODO: Llama al método Change() n veces usando un bucle
    }
}
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 C# online