Memento

From CSSEMediaWiki
Revision as of 03:23, 25 November 2010 by WikiSysop (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

The Memento pattern is a way to store historical records of the state (or some portion of the state) of an object. A memento can be thought of as a souvenir. Much as a Mickey Mouse soft toy might bring back memories of what Disneyland was like when you visited, a Memento object allows the object which made it to remember what state it was in when the Memento was constructed. Using this information, it can then restore that previous state.

The object whose historical state we are saving is known as the Originator class for the pattern. The goal is to avoid breaking the encapsulation of the Originator. The Memento objects for a particular Originator are stored in a Caretaker class. The Caretaker object is probably the most crucial part of the pattern, as this object allows for the key feature: It stores each Memento without knowledge of its internal details.

Thus the Originator shares (some of) its internal state with the Memento object, but not to any other class. The state information remains fully encapsulated by the Originator, except when creating a Memento. Ideally, the state information in a Memento object could only be accessed by its Originator object, and no other classes (C++ allows for this with "friend" classes, but Java doesn't AFAIK, not sure about C#). In any case, no classes besides the originator need or should use the Memento.

Contents

Use When

Use the Memento pattern when:

  • You need to save a snapshot of an object's state so that you can maybe restore it later, and
  • You don't want to break the encapsulation of an object by adding getters and setters so that its state can be obtained from the outside.

Structure

From the Gang of Four Design Patterns book:

MementoStructure.png

Participants

Memento

This class stores the internal state of the originator and protects it from access by anyone other than the originator. Caretaker can only see part of the Memento interface, just enough to handle it. Originator, however, sees a much wider interface that it can use to restore itself to a previous state.

Originator

The originator creates a Memento by taking a snapshot of its state and can later use the Memento to restore its state.

Caretaker

The Caretaker keeps the Mementos safe and never looks at the contents of the Memento.(Can this be enforced in Java?)

Consequences

  • Memento preserves the encapsulation of the Originator by not forcing it to add accessors so that its state can be extracted.
  • Memento simplifies the Originator because it doesn't need to hold on to old versions of its state.
  • Using Mementos can be expensive if the Originator has to copy a lot of state to and from the Memento and if the state of the Originator has to be restored frequently.
  • Defining the narrow and wide interfaces for the Memento may be difficult depending on the language you are using.
  • Storing Mementos can be costly if they contain a lot of state. The caretaker may delete them, but it doesn't know how much state the Mementos contain.

Violations

It could be argued that the Memento pattern constitutes a violation of Don't repeat yourself, since the Memento class must maintain duplicates of the Originator's fields. This could possibly be alleviated by abstracting the state out into a separate class so it doesn't have to be defined twice.

Example

You can find here a nicely explained java code example of the Momento Pattern usage in the real world.

Related Patterns

  • Command: Memento can be used to store the state for undoable operations.
  • Iterator: Mementos can be used for iteration.

See also


Personal tools