2.8 KiB
2.8 KiB
obj |
---|
concept |
Memento Pattern
Description:
The Memento Pattern is a behavioral design pattern that allows you to capture and externalize an object's internal state so that the object can be restored to that state later. It is often used to implement undo functionality, snapshots, or checkpoints in an application without exposing the object's internal structure.
How it's Used:
- Originator: Define an originator class (or object) that has an internal state that needs to be saved and restored.
- Memento: Create a memento class that represents the state of the originator object. This class should provide methods to get and set the originator's state.
- Caretaker: Implement a caretaker class that is responsible for keeping track of and managing the memento objects. The caretaker should have a collection to store multiple mementos if needed.
- Save and Restore: The originator can create memento objects to save its state, and the caretaker can store these mementos. When needed, the originator can restore its state from a memento provided by the caretaker.
Example:
Let's create an example of the Memento Pattern in Rust to implement a simple text editor with undo functionality.
// Originator: TextEditor
struct TextEditor {
text: String,
}
impl TextEditor {
fn new() -> Self {
TextEditor { text: String::new() }
}
fn set_text(&mut self, text: String) {
self.text = text;
}
fn get_text(&self) -> String {
self.text.clone()
}
fn create_memento(&self) -> EditorMemento {
EditorMemento::new(self.text.clone())
}
fn restore_from_memento(&mut self, memento: EditorMemento) {
self.text = memento.get_saved_text();
}
}
// Memento: EditorMemento
struct EditorMemento {
saved_text: String,
}
impl EditorMemento {
fn new(text: String) -> Self {
EditorMemento { saved_text: text }
}
fn get_saved_text(&self) -> String {
self.saved_text.clone()
}
}
// Caretaker: EditorHistory
struct EditorHistory {
mementos: Vec<EditorMemento>,
}
impl EditorHistory {
fn new() -> Self {
EditorHistory { mementos: Vec::new() }
}
fn add_memento(&mut self, memento: EditorMemento) {
self.mementos.push(memento);
}
fn get_memento(&self, index: usize) -> Option<&EditorMemento> {
self.mementos.get(index)
}
}
fn main() {
let mut editor = TextEditor::new();
let mut history = EditorHistory::new();
editor.set_text(String::from("First version"));
history.add_memento(editor.create_memento());
editor.set_text(String::from("Second version"));
history.add_memento(editor.create_memento());
editor.restore_from_memento(history.get_memento(0).unwrap().clone());
println!("Restored version: {}", editor.get_text());
}