|
Principes |
Ce pattern est à utiliser lorsque l'on souhaite modifier dynamiquement le comportement d'un objet quand son état interne change.
Il permet de remplacer des déclarations conditionnelles (if imbriqués) dans les opérations (méthodes), éventuellement basées sur des enum (états) identiques dans des opérations distinctes.

Architecture du pattern State
Context délègue les requêtes à son _state (concret) courant.
Ces requêtes peuvent éventuellement prendre en paramètre
la référence sur le contexte (_etat->handle(*this)),
pour deux raisons possibles :
L'utilisateur accède au context (qui joue le rôle d'interface), mais jamais aux états (dont il n'a pas connaissance).
La responsabilité de modifier l'état courant est :
Le pattern isole les comportements spécifiques d'états et partitionne les différents comportements.
Il rend les transitions d'état plus explicites, et plus nettes (étant donné que la granularité est le State, il n'existe pas d'état transitoire constitué de plusieurs variables non entièrement affectées): un état correspond à une instance, et non pas à n variables internes.
Les objets State peuvent être partagés si il n'y a pas de variables d'instances (Cf. Pattern "Poids Mouche"): cela pourra éventuellement orienter l'implentation.
Qui définit les transitions d'état?
Alternative à cette première solution: transitions pilotées par table (Se référer au livre).
Compromis sur la durée de vie des ConcreteState: faut-il les créer/détruire à chaque utilisation ou une unique fois?
A chaque utilisation :
Tout créer au début et tout détruire à la fin:
Il faut donc faire un compromis entre le coût mémoire, et le coût d'instanciation.
Utilisation de l'héritage dynamique: impossible en C++ (Se référer au livre).
State implente le comportement par défaut de toutes les requêtes qui lui sont déléguées.
La classe State est déclarée "friend" de Context pour accéder facilement le méthode privée Contexte::changeState(State&) (comme State::changeState(Contexte&, State&) )
Chaque ConcretState est un Singleton (pas besoin de conserver des références sur les ConcretState)
Chaque requête d'un ConcretState se termine par changeState(Contexte&, ConcreteStateXXX::instance())
Le Poid Mouche, pour savoir quand et comment partager les objets State.
Le Singleton : les objets State sont souvent des Singleton.
Question: Les méthodes de State
sont elles virtuelles pures ?
Réponse: Oui.
Etant donné la forte dépendance des classes entre elles, voire des classes imbriquées, l'implentation de ce pattern est difficilement réutilisable.
03/11/2001