Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.algorithmstudy.pattern.behavoiral.chainofresposibility

class AuthenticationHeader(val token: String?, var next: HandlerChain? = null) : HandlerChain {
override fun addHeader(inputHeader: String): String =
"$inputHeader\nAuthorization : $token".let {
next?.addHeader(it) ?: it
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.algorithmstudy.pattern.behavoiral.chainofresposibility

class BodyPayloadHeader(val body: String?, var next: HandlerChain? = null) : HandlerChain {
override fun addHeader(inputHeader: String): String =
"$inputHeader\nContentType : $body".let {
next?.addHeader(it) ?: it
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.algorithmstudy.pattern.behavoiral.chainofresposibility

class ContentTypeHeader(val contentType: String?, var next: HandlerChain? = null) : HandlerChain {
override fun addHeader(inputHeader: String): String =
"$inputHeader\nContentType : $contentType".let {
next?.addHeader(it) ?: it
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.example.algorithmstudy.pattern.behavoiral.chainofresposibility

interface HandlerChain {
fun addHeader(inputHeader: String): String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.algorithmstudy.pattern.behavoiral.mediator

class ComponentA(private val mediator: Mediator) {
fun operationA() {
mediator.method(this, "arg A")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.algorithmstudy.pattern.behavoiral.mediator

class ComponentB(private val mediator: Mediator) {
fun operationB() {
mediator.method(this, "arg B")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.algorithmstudy.pattern.behavoiral.mediator

class ComponentC(private val mediator: Mediator) {
fun operationC() {
mediator.method(this, "arg C")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.algorithmstudy.pattern.behavoiral.mediator

class ConcreteMediator : Mediator {
override fun method(sender: Any, args: Any?) {
when (sender) {
is ComponentA -> println("arg from A : $args")
is ComponentB -> println("arg from B : $args")
is ComponentC -> println("arg from C : $args")
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.algorithmstudy.pattern.behavoiral.mediator

/**
* ref : https://asvid.github.io/kotlin_mediator_pattern
*/
interface Mediator {
fun method(sender: Any, args: Any? = null)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.example.algorithmstudy.pattern.behavoiral.observer

interface IObservable {
val observers: ArrayList<IObserver>

fun add(observer: IObserver) {
observers.add(observer)
}

fun remove(observer: IObserver) {
observers.remove(observer)
}

fun sendUpdateEvent() {
observers.forEach { it.update() }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.algorithmstudy.pattern.behavoiral.observer

/**
* ref : https://www.baeldung.com/kotlin/observer-pattern
*/
interface IObserver {
fun update()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.example.algorithmstudy.pattern.behavoiral.observer

class NewsLetter : IObservable {
override val observers: ArrayList<IObserver> = ArrayList()

var newestArticleUrl = ""
set(value) {
field = value
sendUpdateEvent()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.algorithmstudy.pattern.behavoiral.observer

class NewsReader(private var newsLetter: NewsLetter) : IObserver {
override fun update() {
println("New article : ${newsLetter.newestArticleUrl}")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.example.algorithmstudy.pattern.behavoiral.templatemethod

class Americano : Drink() {
override fun addIngredient() = println("Adding 2 shots of espresso")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.example.algorithmstudy.pattern.behavoiral.templatemethod

/**
* reference :
* - http://www.devll.org/blog/2020/kotlin/template-method-pattern.html
* - https://kimchanjung.github.io/design-pattern/2020/05/28/template-method-pattern/
*/
abstract class Drink {
fun prepareDrink() {
println("prepare ${this.javaClass.simpleName}")

boilWater()
addIngredient()
fillWaterInCup()

println("Finished preparing drink\n")
}

// 템플릿 메소드 : 각 구현 요소에 따라 달라지는 부분
protected abstract fun addIngredient()

// 각 구현 요소들이 공통으로 사용하는 부분
private fun boilWater() = println("Boil water")
private fun fillWaterInCup() = println("Fill cup with hot water")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.example.algorithmstudy.pattern.behavoiral.templatemethod

class OrangeAde : Drink() {
override fun addIngredient() = println("Adding orange")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.example.algorithmstudy.design_pattern

import com.example.algorithmstudy.pattern.behavoiral.chainofresposibility.AuthenticationHeader
import com.example.algorithmstudy.pattern.behavoiral.chainofresposibility.BodyPayloadHeader
import com.example.algorithmstudy.pattern.behavoiral.chainofresposibility.ContentTypeHeader
import org.junit.Test

/**
* ChainOfResponsibility 패턴
*
* - https://medium.com/@catalinstefan/chain-of-responsibility-design-pattern-in-kotlin-b62f86be274f
* - 체인 형태로 이어 호출을 해야 하는 요구사항에서, 각 호출 단계별로 호출의 유효성과 오류를 확인 가능하며, 이상이 없는 경우 다음 체인까지 진행하도록 하는 패턴
*/
class ChainOfResponsibilityTest {

@Test
fun testChainOfResponsibility() {
val authenticationHeader = AuthenticationHeader("111")
val contentTypeHeader = ContentTypeHeader("json")
val bodyPayloadHdader = BodyPayloadHeader("Body: body")

authenticationHeader.next = contentTypeHeader
contentTypeHeader.next = bodyPayloadHdader

val messageWithAuth = authenticationHeader.addHeader("HEADERS WITH AUTHENTICATION")
println(messageWithAuth)

val messageWithoutAuth = contentTypeHeader.addHeader("HEADERS WITH AUTHENTICATION")
println(messageWithoutAuth)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.example.algorithmstudy.design_pattern

import com.example.algorithmstudy.pattern.behavoiral.mediator.ComponentA
import com.example.algorithmstudy.pattern.behavoiral.mediator.ComponentB
import com.example.algorithmstudy.pattern.behavoiral.mediator.ComponentC
import com.example.algorithmstudy.pattern.behavoiral.mediator.ConcreteMediator
import org.junit.Test

/**
* Mediator Pattern
*
* - 컴포넌트들은 Mediator를 reference로 가지며, 서로가 소통할 일은 없음
* - Mediator는 각 컴포넌트들을 판단해 각각 필요한 동작을 수행하도록 조정함(말대로 중재자)
*/
class MediatorTest {

@Test
fun mediatorTest() {
ConcreteMediator().apply {
val componentA = ComponentA(this)
val componentB = ComponentB(this)
val componentC = ComponentC(this)

method(componentA)
method(componentB)
method(componentC)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.example.algorithmstudy.design_pattern

import com.example.algorithmstudy.pattern.behavoiral.observer.NewsLetter
import com.example.algorithmstudy.pattern.behavoiral.observer.NewsReader
import org.junit.Test

/**
* Observer Pattern test
*/
class ObserverTest {

@Test
fun TestObserverPattern() {
val newsLetter = NewsLetter()
val reader = NewsReader(newsLetter)

newsLetter.add(reader)
newsLetter.newestArticleUrl = "news 1"
newsLetter.newestArticleUrl = "news 2"
newsLetter.newestArticleUrl = "news 3"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.example.algorithmstudy.design_pattern

import com.example.algorithmstudy.pattern.behavoiral.templatemethod.Americano
import com.example.algorithmstudy.pattern.behavoiral.templatemethod.OrangeAde
import org.junit.Test

/**
* TemplateMethod 패턴
*
* - 공통된 function들은 함께 사용하되, 각 구현 요소별로 다르게 수행할 function을 각각 정의해 사용 가능한 패턴
*/
class TemplateMethodTest {

@Test
fun testTemplateMethod() {
val americano = Americano()
val orangeAde = OrangeAde()

americano.prepareDrink()
orangeAde.prepareDrink()
}
}