Le design pattern Memento
Description
Le design pattern Memento a pour but de sauvegarder et de restaurer l’état d’un objet sans en violer l’encapsulation.
Exemple
Lors de l’achat en ligne d’un véhicule neuf, le client peut choisir des options supplémentaires qui vont être ajoutées à son chariot. Cependant, il existe des options incompatibles comme, par exemple, les sièges sportifs qui sont incompatibles avec les sièges en cuir ou les accoudoirs.
La conséquence de cette incompatibilité est que si les accoudoirs ont été choisis et qu’ensuite les sièges sportifs sont choisis, l’option des accoudoirs est retirée du chariot.
Nous désirons ensuite ajouter une option d’annulation de la dernière opération effectuée dans le chariot. Retirer la dernière option ajoutée n’est pas suffisant car il faut aussi remettre les options présentes et qui ont été retirées pour cause d’incompatibilité. Une solution consiste à mémoriser l’état du chariot avant l’ajout d’une nouvelle option.
Par la suite, nous souhaitons étendre ce mécanisme pour gérer un historique des états du chariot et pouvoir revenir à n’importe quel état. Il faut alors, dans ce cas, mémoriser tous les états successifs du chariot.
Pour préserver l’encapsulation de l’objet représentant le chariot, une solution consisterait à mémoriser...
Structure
1. Diagramme de classes
La figure 23.2 détaille la structure générique du design pattern Memento.
Figure 23.2 - Structure du design pattern Memento
2. Participants
Les participants au design pattern Memento sont les suivants :
-
Memento est la classe des mémentos qui sont les objets qui mémorisent l’état interne des objets d’origine (ou une partie de cet état). Le mémento possède deux interfaces : une interface complète destinée aux objets d’origine qui offre la possibilité de mémoriser et restaurer leur état et une interface réduite pour les objets de gestion de l’état qui n’ont pas le droit d’accéder à l’état interne des objets d’origine.
-
ObjetOrigine (ChariotOption) est la classe des objets qui créent un mémento pour mémoriser leur état interne qu’ils peuvent également restaurer à partir d’un mémento.
-
GestionEtat est responsable de la gestion des mémentos et n’accède pas à l’état interne des objets d’origine.
3. Collaborations
Une instance de GestionEtat demande un mémento à l’objet d’origine par appel de la méthode creeMemento, le sauvegarde et en cas de besoin d’annulation et de retour à l’état mémorisé...
Domaines d’application
Le design pattern Memento est utilisé dans le cas où l’état interne d’un objet doit être mémorisé (totalement ou en partie) afin de pouvoir être restauré ultérieurement sans que l’encapsulation de cet objet ne doive être violée.
Exemple en PHP
Nous commençons la présentation de l’exemple PHP par le mémento. Celui-ci est décrit par l’interface MementoInterface et la classe concrète Memento. La classe contient les méthodes getEtat et setEtat dont l’invocation est réservée au seul chariot.
Le mémento stocke l’état du chariot d’options, à savoir une liste qui est construite par réplication de la liste des options du chariot.
<?php
declare(strict_types=1);
namespace ENI\DesignPatterns\Memento;
interface MementoInterface
{
public function setEtat(ListeOptionVehicule $options): void;
public function getEtat(): ListeOptionVehicule;
}
<?php
declare(strict_types=1);
namespace ENI\DesignPatterns\Memento;
class Memento implements MementoInterface
{
protected ListeOptionVehicule $options;
public function __construct()
{
$this->options = new ListeOptionVehicule();
}
public function setEtat(ListeOptionVehicule $options): void
{
$this->options->effacer();
$this->options->ajout($options);
}
public function getEtat(): ListeOptionVehicule
{
return $this->options;
}
}
La classe Memento utilise la classe ListeOptionVehicule dont le code source est fourni ci-dessous. Cette classe gère une liste d’options sous la forme d’un tableau.
<?php
declare(strict_types=1);
namespace...