Articoli di programmazione

Design patterns in pillole: Memento

Memento permette di memorizzare lo stato di un oggetto esternamente, per poi richiamarlo all'occorrenza

memento_pattern.png
Memento è un pattern molto utile quando siamo in presenza di oggetti con uno stato. Capita spesso di mutare lo stato di un oggetto e doverlo ripristinare in determinate condizioni, pensiamo ad esempio a quant è utile la funzione "Undo" (Ctrl + Z) nella nostra attività quotidiana al computer, perché magari abbiamo sbagliato ad incollare qualcosa e vogliamo tornare alla versione precedente del nostro foglio Word. Memento è uno dei modi per ottenere questo.

La classe Originator possiede uno stato ed espone un oggetto Memento, più alcuni metodi come SaveToMemento e RestoreFromMemento, rispettivamente per leggere e sovrascrivere il proprio stato con quello di un dato Memento.
L'oggetto CareTaker si occupa di salvare gli stati di Originator e tenerli in memoria in una lista, per ripristinarli eventualmente in futuro. In una situazione reale CareTaker sarebbe scritto in modo molto diverso da questo esempio, in quanto la modifica dello stato tramite Set non avverrebbe con tutta probabilità al suo interno, o quantomeno non nel modo qui descritto. Il codice però serve per capire come CareTaker effettui il metodo RestoreFromMemento, il passaggio cioè in cui lo stato viene ripristinato partendo da un Memento salvato in precedenza:

class Originator
{
private string state;

public void Set(string state)
{
this.state = state;
}

public Memento SaveToMemento()
{
return new Memento(state);
}

public void RestoreFromMemento(Memento memento)
{
state = memento.SavedState;
}

public class Memento
{
public readonly string SavedState;

public Memento(string stateToSave)
{
SavedState = stateToSave;
}
}
}

public class Caretaker
{
public void Execute()
{
List savedStates = new List();

Originator originator = new Originator();
originator.Set("State1");
savedStates.Add(originator.SaveToMemento());
originator.Set("State2");
savedStates.Add(originator.SaveToMemento());
originator.Set("State3");
savedStates.Add(originator.SaveToMemento());
originator.Set("State4");

originator.RestoreFromMemento(savedStates[1]);
}
}


#programmazione #designPatterns