Memento Pattern – salvarea și restaurarea stării obiectelor

  • Doru Bulubasa
  • 12 January 2026

În aplicațiile reale apar frecvent cerințe precum Undo / Redo, istoric al modificărilor, revenire la o stare anterioară sau snapshot-uri de stare.

Problema apare atunci când vrem să salvăm starea unui obiect fără să-i expunem structura internă.

Aici intervine Memento Pattern, un behavioral design pattern care ne ajută să:

  • salvăm starea unui obiect,

  • restaurăm acea stare ulterior,

  • fără a încălca principiul encapsulation.


Problema pe care o rezolvă Memento Pattern

Să presupunem că avem un obiect complex (ex: document, formular, editor de text):

  • are multe proprietăți interne;

  • starea se modifică frecvent;

  • avem nevoie de undo / redo.

❌ Soluții greșite:

  • expunerea proprietăților interne;

  • copierea obiectului complet;

  • logica de undo împrăștiată peste tot în cod.

✅ Soluția corectă:

Obiectul își creează singur un „snapshot” al stării → Memento.

Structura pattern-ului

Memento Pattern implică trei roluri clare:

1️⃣ Originator

  • obiectul a cărui stare trebuie salvată;

  • creează și restaurează memento-uri.

2️⃣ Memento

  • conține starea internă;

  • este opac pentru restul aplicației.

3️⃣ Caretaker

  • gestionează lista de memento-uri;

  • nu cunoaște conținutul acestora.


Diagramă conceptuală (simplificată)

Caretaker ---> Memento <--- Originator
                                ^
                                 |
                 creează / restaurează

 


Exemplu practic în C# – Undo pentru un document

🎯 Scenariul

Avem un editor de documente care:

  • modifică textul;

  • permite undo.


1️⃣ Memento – snapshot-ul stării

public class DocumentMemento
{
    public string Content { get; }

    public DocumentMemento(string content)
    {
        Content = content;
    }
}

🔒 Observație:

Memento doar stochează starea, nu conține logică.


2️⃣ Originator – obiectul principal

public class Document
{
    public string Content { get; private set; } = string.Empty;

    public void Write(string text)
    {
        Content += text;
    }

    public DocumentMemento Save()
    {
        return new DocumentMemento(Content);
    }

    public void Restore(DocumentMemento memento)
    {
        Content = memento.Content;
    }
}

📌 Documentul:

  • își creează singur snapshot-ul;

  • știe cum să-și restaureze starea.


3️⃣ Caretaker – managerul de undo

public class DocumentHistory
{
    private readonly Stack<DocumentMemento> _history = new();

    public void Save(DocumentMemento memento)
    {
        _history.Push(memento);
    }

    public DocumentMemento? Undo()
    {
        return _history.Count > 0 ? _history.Pop() : null;
    }
}

🔐 Caretaker-ul:

  • nu știe ce conține memento-ul;

  • doar îl stochează și îl returnează.


4️⃣ Utilizare

var document = new Document();
var history = new DocumentHistory();

document.Write("Hello ");
history.Save(document.Save());

document.Write("World!");
history.Save(document.Save());

Console.WriteLine(document.Content); // Hello World!

var previousState = history.Undo();
if (previousState != null)
{
    document.Restore(previousState);
}

Console.WriteLine(document.Content); // Hello 


Beneficii

✅ Menține encapsulation

✅ Cod curat pentru undo/redo

✅ Separare clară a responsabilităților

✅ Ușor de extins (multi-level undo, redo stack)


Dezavantaje

⚠️ Consum de memorie (multe snapshot-uri)

⚠️ Necesită atenție la obiecte foarte mari

⚠️ Poate deveni costisitor fără limitare de istoric


Când să folosești Memento Pattern

✔ Undo / Redo

✔ Istoric modificări

✔ Snapshot-uri de stare

✔ Editoare, formulare, configurări

✔ Aplicații desktop, web, enterprise

❌ Evită dacă:

  • starea este trivială;

  • nu ai nevoie de restaurare;

  • obiectele sunt foarte mari și mutate frecvent.


Memento Pattern vs alte pattern-uri

Pattern

Scop

Memento

Salvarea stării

Command

Undo prin inversarea acțiunilor

Prototype

Copiere obiect

State

Comportament în funcție de stare

📌 Memento ≠ Command, dar se folosesc frecvent împreună.


Concluzie

Memento Pattern este soluția elegantă pentru gestionarea stării fără compromisuri arhitecturale.

Este indispensabil atunci când vrei funcționalități de tip undo/redo fără a transforma codul într-un „monstru” greu de întreținut.

Scrie un comentariu

Adresa de mail nu va fi publicata. Campurile obligatorii sunt marcate cu *