Memento Pattern


Everyone has used the undo button. Life would have been impossible without it! Memento pattern provides something similar. It is used to restore state of an object to a previous state. As your application is progressing, you may want to save checkpoints in your application and restore back to those checkpoints later. Memento pattern provides for just this.

The memento pattern consists of these participants

  • Originator : the object for which the state is to be saved. It creates the memento and uses it in future to undo.
  • Memento : the object that is going to maintain the state of originator. It's just a POJO.
  • Caretaker : the object that keeps track of multiple memento. Like maintaining savepoints.

Here is an example implementation of the memento pattern

package net.thewiz.memento;

import java.util.List; 
import java.util.ArrayList; 

class Memory { 
	private String time; 

	public void set(String time) { 
		System.out.println("Setting time to " + time); 
		this.time = time; 
	} 

	public Memento saveToMemento() { 
		System.out.println("Saving time to Memento"); 
		return new Memento(time); 
	} 

	public void restoreFromMemento(Memento memento) { 
		time = memento.getSavedTime(); 
		System.out.println("Time restored from Memento: " + time); 
	} 
}

public static class Memento { 
	private final String time; 
	public Memento(String timeToSave) { 
		time = timeToSave; 
	} 

	public String getSavedTime() { 
		return time; 
	} 
} 

class Main { 
	public static void main(String[] args) { 
		List savedTimes = new ArrayList(); 
		Memory m = new Memory(); 

		//time travel and record the eras 
		m.set("1000 B.C."); 
		savedTimes.add(m.saveToMemento()); 
		m.set("1000 A.D."); 
		savedTimes.add(m.saveToMemento()); 
		m.set("2000 A.D."); 
		savedTimes.add(m.saveToMemento()); 
		m.set("4000 A.D."); 

		m.restoreFromMemento(savedTimes.get(0)); 
	} 
} 

One problem is the tight coupling between the object and its memento class. We can use Serialization to achieve memento pattern implementation that is more generic.