Skip to content

Commit ce606a8

Browse files
authored
Merge branch 'master' into observer-pattern
2 parents 8f81477 + c670f0e commit ce606a8

4 files changed

Lines changed: 126 additions & 4 deletions

File tree

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
language: java
2+
sudo: false

README.md

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
# Kotlin OOP and FP Design Patterns
1+
Kotlin OOP and FP Design Patterns
2+
=============
3+
[![Build Status](https://travis-ci.org/CloudCoders/Design-Patterns.svg?branch=master)](https://travis-ci.org/CloudCoders/Design-Patterns)
4+
[![Kotlin version badge](https://img.shields.io/badge/kotlin-1.1.1-blue.svg)](http://kotlinlang.org/)
25

36
## Index
47

@@ -12,7 +15,7 @@
1215
* [ ] [Memento](#memento)
1316
* [ ] [Null Object](#null-object)
1417
* [x] [Observer](#observer)
15-
* [ ] [State](#state)
18+
* [x] [State](#state)
1619
* [ ] [Template](#template)
1720
* [ ] [Visitor](#visitor)
1821
* [Creational Patterns](#creational)
@@ -221,12 +224,57 @@ shop.currentCustomers++ // prints "A new customer entered ..."
221224
shop.currentCustomers-- // prints "A customer left ..."
222225
```
223226

224-
State
227+
[State](/src/main/kotlin/oop/State)
225228
-------
226229

227230
> It allows an object to alter its behaviour when its internal state changes.
228231
229-
**In progress**
232+
We can use Kotlin's [sealed classes](https://kotlinlang.org/docs/reference/sealed-classes.html) to define a restricted hierarchy so that the current _State_ can only have limited values from a set.
233+
234+
### Example
235+
236+
```kotlin
237+
interface State {
238+
fun next(): State
239+
}
240+
241+
sealed class SemaphoreStates : State {
242+
object Red : SemaphoreStates() {
243+
override fun next() = Green
244+
}
245+
246+
object Green : SemaphoreStates() {
247+
override fun next() = Yellow
248+
}
249+
250+
object Yellow : SemaphoreStates() {
251+
override fun next() = Red
252+
}
253+
}
254+
255+
class Semaphore(startingState: State = SemaphoreStates.Red) {
256+
var state = startingState
257+
private set
258+
259+
fun nextLight() {
260+
state = state.next()
261+
}
262+
}
263+
```
264+
265+
### Usage
266+
267+
```kotlin
268+
fun Semaphore.canICross() = this.state is SemaphoreStates.Green
269+
270+
val semaphore = Semaphore()
271+
272+
println(semaphore.canICross()) // false
273+
274+
semaphore.nextLight()
275+
276+
println(semaphore.canICross()) // true
277+
```
230278

231279
[Strategy](/src/main/kotlin/oop/Strategy)
232280
---------

src/main/kotlin/oop/State/State.kt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package oop.State
2+
3+
interface State {
4+
fun next(): State
5+
}
6+
7+
sealed class SemaphoreStates : State {
8+
object Red : SemaphoreStates() {
9+
override fun next() = Green
10+
}
11+
12+
object Green : SemaphoreStates() {
13+
override fun next() = Yellow
14+
}
15+
16+
object Yellow : SemaphoreStates() {
17+
override fun next() = Red
18+
}
19+
}
20+
21+
class Semaphore(startingState: State = SemaphoreStates.Red) {
22+
var state = startingState
23+
private set
24+
25+
fun nextLight() {
26+
state = state.next()
27+
}
28+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package oop.State
2+
3+
import org.hamcrest.CoreMatchers.instanceOf
4+
import org.junit.Assert.assertThat
5+
import org.junit.Test
6+
7+
class StateTest {
8+
9+
@Test
10+
fun `semaphore should start in red colour`() {
11+
val semaphore = Semaphore()
12+
13+
assertThat(semaphore.state, instanceOf(SemaphoreStates.Red::class.java))
14+
}
15+
16+
@Test
17+
fun `semaphore should change state red to green`(){
18+
val semaphore = Semaphore()
19+
20+
semaphore.nextLight()
21+
22+
assertThat(semaphore.state, instanceOf(SemaphoreStates.Green::class.java))
23+
}
24+
25+
@Test
26+
fun `semaphore should change state green to yellow`(){
27+
val semaphore = Semaphore()
28+
29+
semaphore.nextLight() //red to green
30+
semaphore.nextLight() //green to yellow
31+
32+
assertThat(semaphore.state, instanceOf(SemaphoreStates.Yellow::class.java))
33+
}
34+
35+
@Test
36+
fun `semaphore should change state yellow to red`(){
37+
val semaphore = Semaphore(SemaphoreStates.Yellow)
38+
39+
semaphore.nextLight() //yellow to red
40+
41+
assertThat(semaphore.state, instanceOf(SemaphoreStates.Red::class.java))
42+
}
43+
44+
}

0 commit comments

Comments
 (0)