The memento pattern is about capturing and storing the current state of an object so that it can be restored later on in a smooth manner. This pattern has three players:
- The originator is an object that has an internal state.
- The caretaker is planning to do something that might change the originator state. But in case of any problems, it wants to be able to undo (or rollback) the change.
- To accomplish this, the caretaker starts off by asking the originator for a memento object. After this, the caretaker performs the mutation/operations. If some trouble ensues, it returns the memento object to the originator.
The important thing in this pattern is that the memento object is opaque, and thus encapsulation of the originator object is not broken.
The code for the pattern is given here:
// Originator
type Originator struct {
state string
}
func (o *Originator) GetState() string {
return o.state
}
func (o *Originator) SetState(state string) {
fmt.Println("Setting state to " + state)
o.state = state
}
func (o *Originator) GetMemento() Memento {
// externalize state to Momemto objct
return Memento{o.state}
}
func (o *Originator) Restore(memento Memento) {
// restore state
o.state = memento.GetState()
}
// Momento
type Memento struct {
serializedState string
}
func (m *Memento) GetState() string {
return m.serializedState
}
// caretaker
func Caretaker() {
// assume that A is the original state of the Orginator
theOriginator:= Originator{"A"}
theOriginator.SetState("A")
fmt.Println("theOriginator state = ", theOriginator.GetState() )
// before mutating, get an momemto
theMomemto:= theOriginator.GetMemento()
// mutate to unclean
theOriginator.SetState("unclean")
fmt.Println("theOriginator state = ", theOriginator.GetState() )
// rollback
theOriginator.Restore(theMomemto)
fmt.Println("RESTORED: theOriginator state = ", theOriginator.GetState() )
}