diff --git a/README.md b/README.md index 44b0ee7..1b8451e 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Kotlin OOP and FP Design Patterns * [ ] [Interpreter](#interpreter) * [ ] [Iterator](#iterator) * [ ] [Mediator](#mediator) - * [ ] [Memento](#memento) + * [x] [Memento](#memento) * [ ] [Null Object](#null-object) * [x] [Observer](#observer) * [x] [State](#state) @@ -174,12 +174,40 @@ Mediator **In progress** -Memento +[Memento](/src/main/kotlin/oop/Memento) --------- > It captures and externalizes an object's internal state so it can get back to this state later without violating encapsulation -**In progress** +### Example + +```kotlin +data class Memento(val state: T) + +class Originator(var state: T) { + fun saveToMemento() = Memento(state) + fun loadFromMemento(memento: Memento) { + state = memento.state + } +} + +class CareTaker { + val mementoList = mutableListOf>() +} +``` + +### Usage + +```kotlin +val changingClass = Originator("Hello world") +val states = CareTaker() + +changingClass.state += "!" +states.mementoList.add(changingClass.saveToMemento()) + +changingClass.state = "I've made a mistake :(" +changingClass.loadFromMemento(states.mementoList[0]) +``` Null Object ----------- diff --git a/src/main/kotlin/oop/Memento/CareTaker.kt b/src/main/kotlin/oop/Memento/CareTaker.kt new file mode 100644 index 0000000..9d9b66e --- /dev/null +++ b/src/main/kotlin/oop/Memento/CareTaker.kt @@ -0,0 +1,11 @@ +package oop.Memento + +class CareTaker { + private val mementoList = mutableListOf>() + + fun addMemento(memento: Memento) { + mementoList.add(memento) + } + + fun getMemento(index: Int) : Memento? = mementoList[index] +} diff --git a/src/main/kotlin/oop/Memento/Memento.kt b/src/main/kotlin/oop/Memento/Memento.kt new file mode 100644 index 0000000..9a99b72 --- /dev/null +++ b/src/main/kotlin/oop/Memento/Memento.kt @@ -0,0 +1,3 @@ +package oop.Memento + +data class Memento(val state: T) diff --git a/src/main/kotlin/oop/Memento/Originator.kt b/src/main/kotlin/oop/Memento/Originator.kt new file mode 100644 index 0000000..a0dd5cc --- /dev/null +++ b/src/main/kotlin/oop/Memento/Originator.kt @@ -0,0 +1,8 @@ +package oop.Memento + +class Originator(var state : T) { + fun saveToMemento() = Memento(state) + fun loadFromMemento(memento: Memento) { + state = memento.state + } +} diff --git a/src/test/kotlin/oop/Memento/MementoTest.kt b/src/test/kotlin/oop/Memento/MementoTest.kt new file mode 100644 index 0000000..d12594e --- /dev/null +++ b/src/test/kotlin/oop/Memento/MementoTest.kt @@ -0,0 +1,43 @@ +package oop.Memento + +import com.natpryce.hamkrest.Matcher +import com.natpryce.hamkrest.assertion.assert +import org.junit.Test + +class MementoTest { + + fun `is`(list: List): Matcher> = Matcher(List::equals, list) + fun `is`(list: Memento): Matcher> = Matcher(Memento::equals, list) + + @Test + fun `memento state should be equal to last originator state`() { + val originator = Originator(emptyList()) + originator.state = listOf(1,2,3) + + val memento = originator.saveToMemento() + + assert.that(originator.state, `is`(memento.state)) + } + + @Test + fun `originator state should be equal to last memento loaded`() { + val memento = Memento(listOf(1,2,3)) + val originator = Originator(emptyList()) + + originator.loadFromMemento(memento) + + assert.that(originator.state, `is`(memento.state)) + } + + @Test + fun `care taker should store mementos`() { + val careTaker = CareTaker>() + val originator = Originator(listOf(1,2,3)) + val memento = originator.saveToMemento() + + careTaker.addMemento(memento) + + assert.that(careTaker.getMemento(0)!!, `is`(memento)) + } + +}