# Memento **Memento** is a behavioral design pattern that lets you save and restore the previous state of an object without revealing the details of its implementation. ![https://refactoring.guru/images/patterns/content/memento/memento-en.png](https://refactoring.guru/images/patterns/content/memento/memento-en.png) ## **Problem** A text editor. ![https://refactoring.guru/images/patterns/diagrams/memento/problem1-en.png](https://refactoring.guru/images/patterns/diagrams/memento/problem1-en.png) - Set style and insert images. - Can undo. ![https://refactoring.guru/images/patterns/diagrams/memento/problem2-en.png](https://refactoring.guru/images/patterns/diagrams/memento/problem2-en.png) - Make it private. - Add variables. - Either expose all internal details of classes, making them too fragile, or restrict access to their state, making it impossible to produce snapshots. Is there any other way to implement the "undo"? ## **Solution** - Snapshots - Memento - Originator - Caretakers - History ![https://refactoring.guru/images/patterns/diagrams/memento/solution-en.png](https://refactoring.guru/images/patterns/diagrams/memento/solution-en.png) ## **Structure** ### **Implementation based on nested classes** ![https://refactoring.guru/images/patterns/diagrams/memento/structure1.png](https://refactoring.guru/images/patterns/diagrams/memento/structure1.png) 1. The **Originator** can produce snapshots, as well as restore its state from snapshots. 2. The **Memento** is a value object that acts as a snapshot of the originator’s state. 3. The **Caretaker** capture the originator’s state, also restored and travel back in history. 4. Caretaker has very limited access to the memento’s fields and methods, which lets it store mementos in a stack but not tamper with their state. ### **Implementation based on an intermediate interface** ![https://refactoring.guru/images/patterns/diagrams/memento/structure2.png](https://refactoring.guru/images/patterns/diagrams/memento/structure2.png) - Cons: need to declare all members of the memento public. ### **Implementation with even stricter encapsulation** ![https://refactoring.guru/images/patterns/diagrams/memento/structure3.png](https://refactoring.guru/images/patterns/diagrams/memento/structure3.png) ## **Applicability** **Want to produce snapshots of the object’s state to be able to restore a previous state of the object.** **When direct access to the object’s fields/getters/setters violates its encapsulation.** >The Memento makes the object itself responsible for creating a snapshot of its state. No other object can read the snapshot, making the original object’s state data safe and secure. ****How to Implement**** 1. Determine what class will play the role of the originator. It’s important to know whether the program uses one central object of this type or multiple smaller ones. 2. Create the memento class. One by one, declare a set of fields that mirror the fields declared inside the originator class. 3. Make the memento class immutable. A memento should accept the data just once, via the constructor. The class should have no setters. 4. If your programming language supports nested classes, nest the memento inside the originator. If not, extract a blank interface from the memento class and make all other objects use it to refer to the memento. You may add some metadata operations to the interface, but nothing that exposes the originator’s state. 5. Add a method for producing mementos to the originator class. The originator should pass its state to the memento via one or multiple arguments of the memento’s constructor. The return type of the method should be of the interface you extracted in the previous step (assuming that you extracted it at all). Under the hood, the memento-producing method should work directly with the memento class. 6. Add a method for restoring the originator’s state to its class. It should accept a memento object as an argument. If you extracted an interface in the previous step, make it the type of the parameter. In this case, you need to typecast the incoming object to the memento class, since the originator needs full access to that object. 7. The caretaker, whether it represents a command object, a history, or something entirely different, should know when to request new mementos from the originator, how to store them and when to restore the originator with a particular memento. 8. The link between caretakers and originators may be moved into the memento class. In this case, each memento must be connected to the originator that had created it. The restoration method would also move to the memento class. However, this would all make sense only if the memento class is nested into originator or the originator class provides sufficient setters for overriding its state. ## **Pros and Cons** - You can produce snapshots of the object’s state without violating its encapsulation. - You can simplify the originator’s code by letting the caretaker maintain the history of the originator’s state. - The app might consume lots of RAM if clients create mementos too often. - Caretakers should track the originator’s lifecycle to be able to destroy obsolete mementos. - Most dynamic programming languages, such as PHP, Python and JavaScript, can’t guarantee that the state within the memento stays untouched. ## **Relations with Other Patterns** - You can use **[Command](https://refactoring.guru/design-patterns/command)** and **[Memento](https://refactoring.guru/design-patterns/memento)** together when implementing “undo”. In this case, commands are responsible for performing various operations over a target object, while mementos save the state of that object just before a command gets executed. - You can use **[Memento](https://refactoring.guru/design-patterns/memento)** along with **[Iterator](https://refactoring.guru/design-patterns/iterator)** to capture the current iteration state and roll it back if necessary. - Sometimes **[Prototype](https://refactoring.guru/design-patterns/prototype)** can be a simpler alternative to **[Memento](https://refactoring.guru/design-patterns/memento)**. This works if the object, the state of which you want to store in the history, is fairly straightforward and doesn’t have links to external resources, or the links are easy to re-establish.