From 365730a9e6ca4ce77cc34481ee7ace8af175951a Mon Sep 17 00:00:00 2001
From: gmgale <gmgale@icloud.com>
Date: Thu, 24 Dec 2020 06:11:19 +0100
Subject: [PATCH] Added memento pattern

---
 README.md                        |  2 +-
 behavioral/memento.md            | 10 ++++++++++
 behavioral/memento/caretaker.go  | 13 +++++++++++++
 behavioral/memento/main.go       | 30 ++++++++++++++++++++++++++++++
 behavioral/memento/memento.go    |  9 +++++++++
 behavioral/memento/originator.go | 21 +++++++++++++++++++++
 6 files changed, 84 insertions(+), 1 deletion(-)
 create mode 100644 behavioral/memento.md
 create mode 100644 behavioral/memento/caretaker.go
 create mode 100644 behavioral/memento/main.go
 create mode 100644 behavioral/memento/memento.go
 create mode 100644 behavioral/memento/originator.go

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
+}