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.

🤖 Întreabă AI despre acest articol

Răspuns generat de AI pe baza acestui articol.
AI scrie răspunsul…

Scrie un comentariu

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