State Pattern vs Memento Pattern
1. State Pattern
- Changement de comportement selon l'état : Utilisé lorsque le comportement d'un objet change en fonction de son état interne.
- Modularité et extensibilité : Chaque état est encapsulé dans une classe spécifique, ce qui permet une gestion propre et modulaire des transitions entre les états.
- Exemple : Gestion des commandes dans une boutique en ligne, où une commande passe par différents états comme "nouvelle", "en traitement", "expédiée", et "livrée".
2. Memento Pattern
- Sauvegarde et restauration d'état : Utilisé pour capturer l'état interne d'un objet afin de le restaurer plus tard sans violer l'encapsulation.
- Annulation et restauration : Principalement utilisé pour implémenter des fonctionnalités d'annulation (undo) ou de restauration dans des systèmes comme les éditeurs de texte ou de gestion de versions.
- Exemple : Un éditeur de texte où l'utilisateur peut revenir à des versions précédentes du contenu grâce à une fonctionnalité d'annulation.
Comparaison directe :
| Caractéristique | State Pattern | Memento Pattern |
|---|---|---|
| Changement de comportement | Basé sur l'état courant de l'objet. | Sauvegarde et restauration d'un état antérieur. |
| Encapsulation d'état | Chaque état est encapsulé dans une classe distincte. | L'état est sauvegardé dans un objet Memento. |
| Gestion des transitions | Les transitions d'états sont gérées par l'objet lui-même. | L'objet Caretaker gère l'historique des états. |
| Utilisation | Utilisé pour moduler le comportement en fonction de l'état courant. | Utilisé pour restaurer des états passés. |
| Exemple | Système de gestion de commande dans une boutique en ligne. | Fonctionnalité d'annulation dans un éditeur de texte. |
Exemples
Imaginons que tu développes un système pour un personnage de jeu vidéo qui peut changer d'état (courir, sauter) et peut également annuler une action pour revenir à un état précédent.
1. State Pattern
Le personnage change de comportement selon son état (par exemple, courir ou sauter).
// States
class RunningState {
public function handle() {}
}
class JumpingState {
public function handle() {}
}
// Context
class Character {
public function action($state) {
$state->handle();
}
}
// Utilisation
$character = new Character();
$character->action(new RunningState()); // Le personnage court.
$character->action(new JumpingState()); // Le personnage saute.
2. Memento Pattern
Le personnage peut annuler une action et revenir à un état précédent (par exemple, revenir à l'état de course après un saut).
// Memento
class Memento {
public $state;
public function __construct($state) {
$this->state = $state;
}
}
// Originator
class Character {
private $state;
public function setState($state) {
$this->state = $state;
}
public function saveState() {
return new Memento($this->state);
}
public function restoreState($memento) {
$this->state = $memento->state;
}
}
// Caretaker
class History {
private $history = [];
public function save($memento) {
$this->history[] = $memento;
}
public function undo() {
return array_pop($this->history);
}
}
// Utilisation
$character = new Character();
$history = new History();
$character->setState("Courir");
$history->save($character->saveState());
$character->setState("Sauter");
// Annuler
$character->restoreState($history->undo());
Explications
Dans le State Pattern, le personnage change de comportement en fonction de son état. Chaque état (courir, sauter) correspond à un comportement distinct encapsulé dans une classe. Le personnage ne garde aucune trace de ses états passés : il réagit simplement à son état actuel.
Dans le Memento Pattern, le personnage sauvegarde son état à chaque changement, permettant de revenir à un état précédent. Cela permet d'implémenter des fonctionnalités comme l'annulation (undo). Le comportement ne change pas directement en fonction de l'état actuel, mais le personnage peut revenir à un état antérieur lorsqu'une action est annulée.
Ainsi, le State Pattern gère le comportement dynamique à travers des états, tandis que le Memento Pattern se concentre sur la restauration d'un état antérieur.
Cas d'utilisation des patterns
Le State Pattern est particulièrement utile dans des situations où un objet doit changer de comportement en fonction de son état courant. Il est idéal pour des systèmes ayant des transitions d'état bien définies, comme les machines à états, les processus de commande dans le commerce électronique (nouvelle commande, en traitement, expédiée, livrée), ou les systèmes de workflow. Ce pattern permet d'encapsuler chaque état dans une classe distincte, facilitant la gestion des transitions et rendant le code plus modulaire et maintenable.
Le Memento Pattern, quant à lui, est fréquemment utilisé dans des systèmes où il est nécessaire de sauvegarder et restaurer des états précédents, sans violer le principe d'encapsulation. Il est particulièrement utile pour des fonctionnalités comme l'annulation (undo) dans des éditeurs de texte ou des systèmes de gestion de versions, où l'utilisateur doit pouvoir revenir à un état antérieur à tout moment. Il s'applique également dans des contextes tels que la gestion d'historique dans des applications de navigation ou de gestion de paramètres.
Ces deux patterns, bien que comportementaux, répondent donc à des besoins très différents : l'un pour gérer des transitions dynamiques entre des comportements, l'autre pour gérer la restauration d'états passés.
Conclusion
Bien que le State Pattern et le Memento Pattern soient tous deux des patterns comportementaux, ils répondent à des besoins très différents :
- Le State Pattern est utilisé lorsque le comportement de l'objet doit changer en fonction de son état interne, avec des transitions claires entre plusieurs états.
- Le Memento Pattern est plus adapté pour capturer et restaurer l'état d'un objet, idéal pour des fonctionnalités d'annulation ou de gestion d'historique.
Si tu veux modifier le comportement d'un objet en fonction de son état actuel, le State Pattern est la solution idéale. Par contre, si tu cherches à sauvegarder et restaurer l'état d'un objet, le Memento Pattern est le meilleur choix.