BlackWaspTM
Design Patterns
.NET 1.1+

Memento Design Pattern (2)

The memento pattern is a design pattern that permits the current state of an object to be stored without breaking the rules of encapsulation. The originating object can be modified as required but can be restored to the saved state at any time.

Example Memento

In the remainder of this article we will create an example of the memento design pattern. This example will show some of the classes used in a single-level undo system for a library system. We will include an originator class that represents book details being edited by a user. If the user makes an error, they can perform an undo operation to revert a book to its previous state. Note the private variable holding the UTC timestamp for the last edit time. Also note that the memento has been modified slightly to present the state as read-only properties instead of as a method. This simplifies the retrieval of the values.

public class Book
{
    private string _isbn;
    private string _title;
    private string _author;
    private DateTime _lastEdited;

    public string ISBN
    {
        get { return _isbn; }
        set
        {
            _isbn = value;
            SetLastEdited();
        }
    }

    public string Title
    {
        get { return _title; }
        set
        {
            _title = value;
            SetLastEdited();
        }
    }

    public string Author
    {
        get { return _author; }
        set
        {
            _author = value;
            SetLastEdited();
        }
    }

    public Book()
    {
        SetLastEdited();
    }

    private void SetLastEdited()
    {
        _lastEdited = DateTime.UtcNow;
    }

    public Memento CreateUndo()
    {
        return new Memento(_isbn, _title, _author, _lastEdited);
    }

    public void RestoreFromUndo(Memento memento)
    {
        _title = memento.Title;
        _author = memento.Author;
        _isbn = memento.ISBN;
        _lastEdited = memento.LastEdited;
    }

    public void ShowBook()
    {
        Console.WriteLine(
            "{0} - '{1}' by {2}, edited {3}.", ISBN, Title, Author, _lastEdited); 
    }
}


public class Memento
{
    public string ISBN { get; private set; }
    public string Title { get; private set; }
    public string Author { get; private set; }
    public DateTime LastEdited { get; private set; }

    public Memento(string isbn, string title, string author, DateTime lastEdited)
    {
        ISBN = isbn;
        Title = title;
        Author = author;
        LastEdited = lastEdited;
    }
}


public class Caretaker
{
    public Memento Memento { get; set; }
}
18 July 2009