diff --git a/README.md b/README.md index 7d9f5f7..31dcde1 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ A curated collection of idiomatic design & application patterns for Go language. | [Chain of Responsibility](/behavioral/chain_of_responsibility.md) | Avoids coupling a sender to receiver by giving more than object a chance to handle the request | ✘ | | [Command](/behavioral/command.md) | Bundles a command and arguments to call later | ✘ | | [Mediator](/behavioral/mediator.md) | Connects objects and acts as a proxy | ✘ | -| [Memento](/behavioral/memento.md) | Generate an opaque token that can be used to go back to a previous state | ✘ | +| [Memento](/behavioral/memento.md) | Generate an opaque token that can be used to go back to a previous state | ✔ | | [Observer](/behavioral/observer.md) | Provide a callback for notification of events/changes to data | ✔ | | [Registry](/behavioral/registry.md) | Keep track of all subclasses of a given class | ✘ | | [State](/behavioral/state.md) | Encapsulates varying behavior for the same object based on its internal state | ✘ | diff --git a/behavioral/memento.md b/behavioral/memento.md new file mode 100644 index 0000000..ffc0a01 --- /dev/null +++ b/behavioral/memento.md @@ -0,0 +1,10 @@ +The [Memento pattern](https://en.wikipedia.org/wiki/Memento_pattern) allows the state of an object to be saved and restored. It helps us write undo-redo operations through the use of the three componants: + +* Originator: It is the actual object whose state is saved as a memento. +* Memento: This is the object which saves the state of the originator +* Caretaker: This is the object that saves multiple mementos. Given an index, it returns the corresponding memento. + +The originator defines two methods. savememento() and restorememento() + +* savememento()- in this method the originator saves its internal state into a memento object. +* restorememento()- this method takes input as a memento object. The originator restores itself to the pass memento. Hence a previous state is restored. \ No newline at end of file diff --git a/behavioral/memento/caretaker.go b/behavioral/memento/caretaker.go new file mode 100644 index 0000000..05688a7 --- /dev/null +++ b/behavioral/memento/caretaker.go @@ -0,0 +1,13 @@ +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] +} diff --git a/behavioral/memento/main.go b/behavioral/memento/main.go new file mode 100644 index 0000000..96dbb6e --- /dev/null +++ b/behavioral/memento/main.go @@ -0,0 +1,30 @@ +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()) +} diff --git a/behavioral/memento/memento.go b/behavioral/memento/memento.go new file mode 100644 index 0000000..a867efe --- /dev/null +++ b/behavioral/memento/memento.go @@ -0,0 +1,9 @@ +package main + +type memento struct{ + state string +} + +func (m *memento) getSavedState() string{ + return m.state +} \ No newline at end of file diff --git a/behavioral/memento/originator.go b/behavioral/memento/originator.go new file mode 100644 index 0000000..aee6717 --- /dev/null +++ b/behavioral/memento/originator.go @@ -0,0 +1,21 @@ +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 +}