Memento (object behavioral pattern)

GoF definition (p. 283):

"Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later."

Originator

  • creates a memento storing a snapshot of its internal state.
  • uses a memento to restore its internal state.

Memento

  • stores the internal state of an originator.
  • protects against access by objects other than the originator (How, exactly? Is this maintaing encapsulation in this way strictly necessary?)

Caretaker

  • Stores mementos

Pros:

  • Memento avoids exposing information that only an originator should manage, but must nevertheless be exposed outside the originator.
  • Allows you to easily restore the previous state of an originator.
  • Mementos can serve as a 'change log'.

Cons:

  • Can quickly become expensive, especially if storing the state of the originator requires a lot of memory.

Example

Originator

class Document
  attr_accessor :text

  def initialize(text="")
    @text = text
  end

  def get_state
    TextMemento.new(@text)
  end

  def restore_state(memento)
    @text = memento.text
  end
end

Memento

class TextMemento
  attr_reader :text

  def initialize(text)
    @text = text
  end
end

Caretaker

class DocumentHistory
  attr_accessor :history

  def initialize
    @history = []
  end

  def push(memento)
    @history.push(memento)
  end

  def pop
    @history.pop
  end
end

Implementation

doc_history = DocumentHistory.new

my_doc = Document.new("This is the old text!")
doc_history.push(my_doc.get_state)
puts my_doc.text

my_doc.text = "This is some new text!"
puts my_doc.text

# restoring the old state from the memento:
my_doc.restore_state(doc_history.pop)
puts my_doc.text

results matching ""

    No results matching ""