Memento Pattern in Haxe: Capturing and Restoring Object States

Explore the Memento Pattern in Haxe, a behavioral design pattern that captures and externalizes an object's internal state without violating encapsulation, enabling state restoration. Learn how to implement the Memento Pattern in Haxe with practical examples and use cases.

6.11 Memento Pattern

The Memento Pattern is a behavioral design pattern that provides the ability to capture and externalize an object’s internal state without violating encapsulation, allowing the state to be restored at a later time. This pattern is particularly useful in scenarios where you need to implement undo functionality or save checkpoints in applications, such as games.

Intent

The primary intent of the Memento Pattern is to:

  • Capture an object’s internal state.
  • Externalize the state without breaking encapsulation.
  • Allow the object to be restored to this state later.

Key Participants

  1. Memento: Stores the internal state of the Originator. It is a snapshot of the Originator’s state.
  2. Originator: Creates a Memento containing a snapshot of its current state and uses the Memento to restore its state.
  3. Caretaker: Manages the Memento. It is responsible for keeping track of the Memento but does not modify or inspect its contents.

Applicability

Use the Memento Pattern when:

  • You need to provide undo functionality.
  • You want to save and restore an object’s state at different points in time.
  • You need to maintain encapsulation boundaries.

Implementing Memento in Haxe

Let’s explore how to implement the Memento Pattern in Haxe with a practical example. We’ll create a simple text editor that supports undo functionality.

Memento Class

The Memento class stores the state of the Originator. In our example, it will store the text content of the editor.

 1class Memento {
 2    private var state:String;
 3
 4    public function new(state:String) {
 5        this.state = state;
 6    }
 7
 8    public function getState():String {
 9        return state;
10    }
11}

Originator

The Originator is the object whose state needs to be saved and restored. It creates a Memento to capture its state and uses it to restore its state.

 1class TextEditor {
 2    private var content:String;
 3
 4    public function new() {
 5        content = "";
 6    }
 7
 8    public function write(text:String):Void {
 9        content += text;
10    }
11
12    public function save():Memento {
13        return new Memento(content);
14    }
15
16    public function restore(memento:Memento):Void {
17        content = memento.getState();
18    }
19
20    public function getContent():String {
21        return content;
22    }
23}

Caretaker

The Caretaker is responsible for managing the Mementos. It keeps track of the Mementos but does not modify or inspect their contents.

 1class Caretaker {
 2    private var mementos:Array<Memento>;
 3
 4    public function new() {
 5        mementos = [];
 6    }
 7
 8    public function addMemento(memento:Memento):Void {
 9        mementos.push(memento);
10    }
11
12    public function getMemento(index:Int):Memento {
13        return mementos[index];
14    }
15}

Using the Memento Pattern

Let’s see how we can use the Memento Pattern to implement undo functionality in our text editor.

 1class Main {
 2    static function main() {
 3        var editor = new TextEditor();
 4        var caretaker = new Caretaker();
 5
 6        editor.write("Hello, ");
 7        caretaker.addMemento(editor.save());
 8
 9        editor.write("world!");
10        caretaker.addMemento(editor.save());
11
12        trace("Current Content: " + editor.getContent());
13
14        // Undo last change
15        editor.restore(caretaker.getMemento(0));
16        trace("After Undo: " + editor.getContent());
17    }
18}

Diagrams

To better understand the Memento Pattern, let’s visualize the interaction between the Originator, Memento, and Caretaker using a sequence diagram.

    sequenceDiagram
	    participant Originator
	    participant Memento
	    participant Caretaker
	
	    Originator->>Memento: Create Memento
	    Caretaker->>Memento: Store Memento
	    Originator->>Memento: Restore from Memento

Design Considerations

  • Encapsulation: The Memento Pattern preserves encapsulation boundaries by not exposing the internal state of the Originator to the Caretaker.
  • Memory Usage: Be mindful of memory usage when storing multiple Mementos, especially if the state is large.
  • Immutable Mementos: Consider making Mementos immutable to prevent accidental modification.

Differences and Similarities

  • Command Pattern: While both patterns can be used to implement undo functionality, the Command Pattern encapsulates a request as an object, whereas the Memento Pattern captures the state of an object.
  • Prototype Pattern: The Prototype Pattern involves cloning objects, which can be used to achieve similar results as the Memento Pattern but with different intent and implementation.

Use Cases and Examples

State Restoration

The Memento Pattern is ideal for implementing undo functionality in applications. By capturing the state of an object at various points, you can easily restore it to a previous state.

Checkpointing

In games or applications where you need to save progress or checkpoints, the Memento Pattern provides a way to capture the state and restore it later.

Try It Yourself

Experiment with the Memento Pattern by modifying the code examples:

  • Add more complex state to the TextEditor class, such as formatting or cursor position.
  • Implement a redo functionality by managing multiple Mementos.
  • Create a history feature that allows navigating through multiple states.

Knowledge Check

  • What is the primary intent of the Memento Pattern?
  • How does the Memento Pattern preserve encapsulation?
  • What are some use cases for the Memento Pattern?

Embrace the Journey

Remember, mastering design patterns is a journey. As you continue to explore and implement patterns like the Memento Pattern, you’ll gain valuable insights into building robust and maintainable software. Keep experimenting, stay curious, and enjoy the journey!

Quiz Time!

Loading quiz…
Revised on Thursday, April 23, 2026