Memento Pattern
Memento is a behavioral design pattern that allows making snapshots of an object’s state and restoring it in future.
The Memento doesn’t compromise the internal structure of the object it works with, as well as data kept inside the snapshots.
Golang Implementation
Example:
The Memento pattern lets us save snapshots for an object’s state. You can use these snapshots to revert the object to the previous state. It’s handy when you need to implement undo-redo operations on an object.
originator.go
package main
type Originator struct {
state string
}
func (e *Originator) createMemento() *Memento {
return &Memento{state: e.state}
}
func (e *Originator) restoreMemento(m *Memento) {
e.state = m.getSavedState()
}
func (e *Originator) setState(state string) {
e.state = state
}
func (e *Originator) getState() string {
return e.state
}
memento.go
package main
type Memento struct {
state string
}
func (m *Memento) getSavedState() string {
return m.state
}
caretaker.go
package main
type Caretaker struct {
mementoArray []*Memento
}
func (c *Caretaker) addMemento(m *Memento) {
c.mementoArray = append(c.mementoArray, m)
}
func (c *Caretaker) getMemento(index int) *Memento {
return c.mementoArray[index]
}
main.go
package main
import "fmt"
func main() {
caretaker := &Caretaker{
mementoArray: make([]*Memento, 0),
}
originator := &Originator{
state: "A",
}
fmt.Printf("Originator Current State: %s\n", originator.getState())
caretaker.addMemento(originator.createMemento())
originator.setState("B")
fmt.Printf("Originator Current State: %s\n", originator.getState())
caretaker.addMemento(originator.createMemento())
originator.setState("C")
fmt.Printf("Originator Current State: %s\n", originator.getState())
caretaker.addMemento(originator.createMemento())
originator.restoreMemento(caretaker.getMemento(1))
fmt.Printf("Restored to State: %s\n", originator.getState())
originator.restoreMemento(caretaker.getMemento(0))
fmt.Printf("Restored to State: %s\n", originator.getState())
}
// Originator Current State: A
// Originator Current State: B
// Originator Current State: C
// Restored to State: B
// Restored to State: A
Rust Implementation
Example:
This is a conceptual example of Memento pattern.
main.rs
trait Memento<T> {
fn restore(self) -> T;
fn print(&self);
}
struct Originator {
state: u32,
}
impl Originator {
pub fn save(&self) -> OriginatorBackup {
OriginatorBackup {
state: self.state.to_string(),
}
}
}
struct OriginatorBackup {
state: String,
}
impl Memento<Originator> for OriginatorBackup {
fn restore(self) -> Originator {
Originator {
state: self.state.parse().unwrap(),
}
}
fn print(&self) {
println!("Originator backup: '{}'", self.state);
}
}
fn main() {
let mut history = Vec::<OriginatorBackup>::new();
let mut originator = Originator { state: 0 };
originator.state = 1;
history.push(originator.save());
originator.state = 2;
history.push(originator.save());
for moment in history.iter() {
moment.print();
}
let originator = history.pop().unwrap().restore();
println!("Restored to state: {}", originator.state);
let originator = history.pop().unwrap().restore();
println!("Restored to state: {}", originator.state);
}
// Originator backup: '1'
// Originator backup: '2'
// Restored to state: 2
// Restored to state: 1