Memento Design Pattern

Type : Behavioral Design Pattern

Summary

Memento design pattern is used when we want to save the state of an object so that we can restore later on.

Advantages

The memento pattern provides a way of recording the internal state of an object in a separate 
object. 

Memento design pattern removes need for multiple creation of the same object for the sole purpose of saving its state. 

The memento simplifies the Originator since the responsibility of managing Memento storage is no longer centralized at the Originator but rather distributed among the Caretakers.

Disadvantages

As the Memento object stores the data of the Originator object, it generally copies the fields that represents state of the originator. Changes in the Originator object could force to change the memento object also.

Details

Memento design pattern is used when we want an option to to get previous state or restore previous version of objects. It has three key components

Originator : It is the object which can change and we want the previous state to be preserved.
CaretakerIt is the helper class that is responsible for storing and restoring the state of the Originator’s state through Memento object.
Memento : It stores internal state of the Originator, it can be an inner class to originator class

Caretaker is at the central of this pattern, only the caretaker object knows about the internal details of the memento object. Memento object is not known to the outside world. Memento object is sufficiently designed so that it can hold the key properties of the originator object.

For example lets consider a Blogpage object which contains some attributes like title, content etc. When the editor edits the blogpage its content gets changed and let's say we want to maintain the previous version of the blogpage. So that we can support undo operations if needed.

Here BlogContent class is the Originator whose state we want to save
Memento object is the object which stores a specific originator instance
Caretaker is the map which holds various versions of the BlogContent object.

Class Diagram


Sample Code


// memento object holding the contents of Originator
public class Memento {

  private String blogTitle;
  private String blogContent;
  private int version;

  public Memento(String t, String c, int v) {
    this.blogTitle = t;
    this.blogContent = c;
    this.version = v;
  }

  public BlogContent getSavedState() {
    return new BlogContent(blogTitle, blogContent);
  }

  public int getVersion() {
    return version;
  }

}


// originator object
public class BlogContent {

  private String blogTitle;
  private String blogContent;
  private int version = 0;

  public BlogContent() {}

  public void write(String bT, String bC) {
    this.blogTitle = bT;
    this.blogContent = bC;
    this.version++;
  }

  public Memento saveToMemento() {
    System.out.println("Originator: Saving to Memento.");
    return new Memento(this.blogTitle, this.blogContent, this.version);
  }

  public BlogContent restoreFromMemento(Memento m) {
    BlogContent state = m.getSavedState();
    this.blogTitle = state.blogTitle;
    this.blogContent = state.blogContent;
    return state;
  }

}

// caretake object
public class CareTaker {

  private Map savedStates = new HashMap();

  public void addMemento(Memento m) {
    savedStates.put(m.getVersion(), m);
  }

  public Memento getMemento(int index) {
    return savedStates.get(index);
  }

}

Comments

Popular posts from this blog

Difference between volatile and synchronized

Converting Java Map to String

Masking Credit Card number in Java