Menu
Coddy logo textTech

Pattern dello Stato

Fa parte della sezione Programmazione orientata agli oggetti del percorso C# di Coddy. Lezione 60 di 70.

Il pattern State è un pattern comportamentale che consente a un oggetto di cambiare comportamento quando cambia il suo stato interno. Invece di usare istruzioni condizionali complesse per gestire stati diversi, incapsuli ogni stato nella propria classe e deleghi il comportamento all'oggetto dello stato corrente.

Il pattern è costituito da tre componenti: un'interfaccia di stato che definisce il comportamento specifico dello stato, classi di stato concrete che implementano tale comportamento e una classe contesto che mantiene un riferimento allo stato corrente:

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");
    }
}

Il contesto contiene lo stato corrente e gli delega le azioni. Gli oggetti stato possono attivare transizioni chiamando SetState() sul contesto:

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();  // Passaggio alla moderazione
doc.Publish();  // Pubblicazione del documento
doc.Publish();  // Già pubblicato

Il pattern State elimina le istruzioni if-else o switch troppo estese che controllano lo stato corrente. Ogni classe di stato gestisce solo il proprio comportamento, rendendo il codice più facile da mantenere ed estendere con nuovi stati.

challenge icon

Sfida

Facile

Costruiamo un sistema di semafori usando il pattern State. I semafori passano ciclicamente attraverso stati distinti (rosso, giallo, verde) e ogni stato determina cosa succede quando il semaforo cambia. Invece di usare condizionali complessi, incapsulerai ogni stato del semaforo nella propria classe.

Organizzerai il codice in tre file:

  • TrafficLightState.cs: Definisci un'interfaccia ITrafficLightState nello spazio dei nomi Traffic con un metodo Change(TrafficLight light). Poi crea tre classi di stato concrete:
    • RedState - quando viene chiamato Change, stampa Red - Stop! Changing to Green... e porta il semaforo allo stato GreenState
    • GreenState - stampa Green - Go! Changing to Yellow... e passa allo stato YellowState
    • YellowState - stampa Yellow - Caution! Changing to Red... e passa allo stato RedState
  • TrafficLight.cs: Crea una classe TrafficLight nello stesso spazio dei nomi. Questa è la classe contesto che mantiene lo stato corrente. Per impostazione predefinita, dovrebbe iniziare nello stato RedState e avere:
    • Un metodo SetState(ITrafficLightState state) che gli oggetti di stato usano per attivare le transizioni
    • Un metodo Change() che delega al metodo Change dello stato corrente
  • Program.cs: Metti insieme tutti gli elementi creando un TrafficLight e passando da uno stato all'altro in base all'input.

Riceverai un input:

  • Il numero di volte in cui cambiare il semaforo (un numero intero)

Crea un TrafficLight (che inizia con il rosso) e chiama Change() il numero di volte specificato.

Ad esempio, se l'input è 3, l'output dovrebbe essere:

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

Se l'input è 5, il semaforo compie un giro completo:

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...

Nota come la classe TrafficLight non contenga alcuna logica sul significato di ciascun colore o su quale venga dopo: tutte queste informazioni si trovano nelle singole classi di stato. Ogni stato è responsabile del proprio comportamento e di attivare la transizione allo stato successivo!

Provalo tu

using System;
using Traffic;

class Program
{
    public static void Main(String[] args)
    {
        // Leggi il numero di volte in cui cambiare il semaforo
        int n = Convert.ToInt32(Console.ReadLine());

        // TODO: Crea un'istanza di TrafficLight (inizia in RedState per impostazione predefinita)

        // TODO: Chiama il metodo Change() n volte usando un ciclo
    }
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore C# online