Menu
Coddy logo textTech

Patron État

Fait partie de la section Programmation Orientée Objet du Journey Dart de Coddy — leçon 98 sur 110.

Le patron d'état (State pattern) permet à un objet de modifier son comportement lorsque son état interne change, donnant l'impression que l'objet a changé de classe. Au lieu d'utiliser des conditions 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 consiste en un Contexte qui maintient une référence à l'état actuel, et des classes d'État qui définissent le comportement pour chaque état possible. Lorsque l'état du contexte change, son comportement change automatiquement :

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());  // Brouillon
  doc.publish();           // Passage en révision...
  print(doc.getStatus());  // En cours de révision
  doc.publish();           // Document publié !
  print(doc.getStatus());  // Publié
}

Chaque classe d'état gère l'action publish() différemment et peut faire passer le document à l'état suivant. La classe Document n'a pas besoin de structures conditionnelles pour vérifier son état actuel — elle délègue simplement à l'objet d'état qui est actuellement actif. Ce patron est idéal pour les objets ayant des modes de comportement distincts, comme le traitement des commandes, les lecteurs multimédias ou les systèmes de flux de travail.

challenge icon

Défi

Facile

Construisons un système de feux de circulation en utilisant le pattern State ! Vous allez créer un feu de circulation qui alterne entre différents états, où chaque état détermine la couleur du feu et comment il passe à l'état suivant.

Vous organiserez votre code en deux fichiers :

  • traffic_light.dart : Ce fichier contient vos classes d'état et le contexte du feu de circulation. Créez une classe abstraite TrafficLightState avec deux méthodes : String getColor() qui retourne la couleur actuelle du feu, et void next(TrafficLight light) qui fait passer le feu à son état suivant. Implémentez trois classes d'état concrètes :
    • RedState - retourne RED comme couleur et affiche Stop! Light is red. quand next() est appelée, puis passe à GreenState
    • GreenState - retourne GREEN comme couleur et affiche Go! Light is green. quand next() est appelée, puis passe à YellowState
    • YellowState - retourne YELLOW comme couleur et affiche Caution! Light is yellow. quand next() est appelée, puis passe à RedState
    Ensuite, créez une classe TrafficLight (le contexte) qui commence en RedState. Elle doit avoir une méthode setState() pour changer l'état actuel, une méthode getColor() qui délègue à l'état actuel, et une méthode change() qui appelle next() sur l'état actuel.
  • main.dart : Importez votre fichier de feu de circulation et démontrez le pattern State en action. Créez un TrafficLight et affichez sa couleur initiale. Appelez ensuite change() trois fois, en affichant la couleur après chaque changement. Cela montrera le feu défilant à travers tous les états et revenant au début.

Remarquez comment la classe TrafficLight n'a besoin d'aucune condition pour déterminer le comportement - chaque état connaît sa propre couleur et quel état vient ensuite. Le feu de circulation délègue simplement à l'état qui est actuellement actif !

Sortie attendue :

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

Aide-mémoire

Le patron d'état (State pattern) permet à un objet de modifier son comportement lorsque son état interne change. Au lieu d'utiliser des structures conditionnelles complexes, chaque état est encapsulé dans sa propre classe.

Le patron se compose de :

  • Contexte (Context) : Maintient une référence vers l'état actuel
  • Classes d'état (State classes) : Définissent le comportement pour chaque état possible

Structure de base :

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 Document {
  DocumentState _state = DraftState();

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

Le contexte délègue le comportement à l'objet d'état actuel. Chaque classe d'état gère les actions différemment et peut effectuer une transition vers l'état suivant. Cela élimine le besoin de conditions pour vérifier l'état actuel.

Idéal pour les objets ayant des modes de comportement distincts comme le traitement des commandes, les lecteurs multimédias ou les systèmes de flux de travail (workflow).

Essayez vous-même

import 'traffic_light.dart';

void main() {
  // TODO: Créer une instance de TrafficLight
  
  // TODO: Afficher la couleur initiale
  
  // TODO: Appeler change() et afficher la couleur (3 fois pour parcourir tous les états)
  // Premier changement : RED -> GREEN
  
  // Deuxième changement : GREEN -> YELLOW
  
  // Troisième changement : YELLOW -> RED
}
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