Menu
Coddy logo textTech

Patron État

Fait partie de la section Programmation Orientée Objet du Journey C# de Coddy — leçon 60 sur 70.

Le pattern State est un patron de conception comportemental qui permet à un objet de changer son comportement lorsque son état interne change. Au lieu d'utiliser des instructions conditionnelles complexes pour gérer différents états, vous encapsulez chaque état dans sa propre classe et déléguez le comportement à l'objet d'état actuel.

Le patron se compose de trois composants : une interface d'état définissant le comportement spécifique à l'état, des classes d'état concrètes implémentant ce comportement, et une classe de contexte qui maintient une référence vers l'état actuel :

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

Le contexte détient l'état actuel et lui délègue les actions. Les objets d'état peuvent déclencher des transitions en appelant SetState() sur le contexte :

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();  // Passage en modération
doc.Publish();  // Publication du document
doc.Publish();  // Déjà publié

Le pattern State élimine les instructions if-else ou switch tentaculaires qui vérifient l'état actuel. Chaque classe d'état gère uniquement son propre comportement, ce qui rend le code plus facile à maintenir et à étendre avec de nouveaux états.

challenge icon

Défi

Facile

Construisons un système de feux de signalisation en utilisant le patron de conception State (État). Les feux de signalisation passent par des états distincts (rouge, jaune, vert), et chaque état détermine ce qui se passe lorsque le feu change. Au lieu d'utiliser des conditions complexes, vous allez encapsuler chaque état du feu dans sa propre classe.

Vous organiserez votre code sur trois fichiers :

  • TrafficLightState.cs : Définissez une interface ITrafficLightState dans l'espace de noms Traffic avec une méthode Change(TrafficLight light). Créez ensuite trois classes d'état concrètes :
    • RedState - lorsque Change est appelée, elle affiche Red - Stop! Changing to Green... et fait passer le feu à GreenState
    • GreenState - affiche Green - Go! Changing to Yellow... et fait passer à YellowState
    • YellowState - affiche Yellow - Caution! Changing to Red... et fait passer à RedState
  • TrafficLight.cs : Créez une classe TrafficLight dans le même espace de noms. C'est votre classe de contexte qui maintient l'état actuel. Elle doit commencer en RedState par défaut et posséder :
    • Une méthode SetState(ITrafficLightState state) que les objets d'état utilisent pour déclencher les transitions
    • Une méthode Change() qui délègue à la méthode Change de l'état actuel
  • Program.cs : Rassemblez le tout en créant un TrafficLight et en effectuant des cycles de changement d'état basés sur l'entrée.

Vous recevrez une entrée :

  • Le nombre de fois qu'il faut changer le feu de signalisation (un entier)

Créez un TrafficLight (qui commence au rouge) et appelez Change() le nombre de fois spécifié.

Par exemple, si l'entrée est 3, la sortie devrait être :

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

Si l'entrée est 5, le feu recommence son cycle :

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

Remarquez comment la classe TrafficLight ne contient aucune logique sur la signification de chaque couleur ou sur ce qui vient ensuite - toute cette connaissance réside dans les classes d'état individuelles. Chaque état est responsable de son propre comportement et du déclenchement de la transition vers l'état suivant !

Aide-mémoire

Le patron d'état (ou State pattern) est un patron de conception comportemental qui permet à un objet de modifier son comportement lorsque son état interne change. Au lieu d'utiliser des instructions conditionnelles complexes, vous encapsulez chaque état dans sa propre classe et déléguez le comportement à l'objet d'état actuel.

Le patron se compose de trois éléments :

  • Interface d'état : Définit le comportement spécifique à l'état
  • Classes d'état concrètes : Implémentent le comportement pour chaque état
  • Classe de contexte : Maintient une référence vers l'état actuel

Exemple d'implémentation :

// Interface d'état
public interface IDocumentState
{
    void Publish(Document doc);
}

// Classes d'état concrètes
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");
    }
}

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

// Utilisation
var doc = new Document();
doc.Publish();  // Moving to moderation
doc.Publish();  // Publishing document
doc.Publish();  // Already published

Le contexte détient l'état actuel et lui délègue les actions. Les objets d'état peuvent déclencher des transitions en appelant SetState() sur le contexte. Cela élimine les instructions if-else ou switch tentaculaires, rendant le code plus facile à maintenir et à étendre avec de nouveaux états.

Essayez vous-même

using System;
using Traffic;

class Program
{
    public static void Main(String[] args)
    {
        // Lire le nombre de fois que le feu de signalisation doit changer
        int n = Convert.ToInt32(Console.ReadLine());

        // TODO: Créer une instance de TrafficLight (commence par RedState par défaut)

        // TODO: Appeler la méthode Change() n fois en utilisant une boucle
    }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet