Intro
์ค๋์ ๊ฐ๋จํ๊ฒ Observer ํจํด์ ๋ํด์ ๊ณต๋ถํด๋ดค์ต๋๋ค. Observer ํจํด์ ์ด๋ค ๊ฐ์ฒด๊ฐ ๋ณํ์ ๋ ๋ฑ๋ก๋(ํน์ ๋ณด๊ณ ์๋) ๊ด์ฐฐ์(Observer)๋ค์๊ฒ ํต์งํ๋, Behavioral Pattern์ ๋๋ค.
Kotlin์์๋ Observer pattern์ ๋ ๊ฐ์ง์ ํํ๋ก ๊ตฌํํ ์๊ฐ ์์ต๋๋ค. ํ๋๋ Standard, ๊ทธ๋ฌ๋๊น ํ๋ฒํ ๋ชจ์ต์ผ๋ก ๊ตฌํ์ด ๊ฐ๋ฅํ๊ณ , ํ๋๋ Kotlin์ observable delagates๋ฅผ ํ์ฉํ ๋ฐฉ๋ฒ์ ๋๋ค.
Standard
๋จผ์ Standardํ๊ฒ ๊ตฌํํ ๋ชจ์ต์ ๋๋ค. Observer ๊ด์ฐฐํ๊ณ ์๋ ๊ฐ์ฒด๊ฐ ๋ณํ์ ๋ Observer์ update๊ฐ ๋์ํ๊ฒ ๋ ๊ฒ๋๋ค.
interface Observer {
fun update()
}
Observable์ Observer๋ค์ ๊ด๋ฆฌํ๋ ์ธํฐํ์ด์ค์ ๋๋ค. Observer๋ฅผ add์ remove ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ๋ฑ๋กํ๊ณ , ๋ฑ๋ก๋ Observer๋ค์๊ฒ ๊ฐ์ฒด๊ฐ ๋ณํํ์์ ์๋ฆฌ๋ ์ญํ ์ ํ๊ฒ ๋ฉ๋๋ค.
interface Observable {
val observers: ArrayList<Observer>
fun add(observer: Observer) {
observers.add(observer)
}
fun remove(observer: Observer) {
observers.remove(observer)
}
fun sendUpdateEvent() {
observers.forEach { it.update() }
}
}
Blog๊ฐ ์ ๋ฐ์ดํธ๊ฐ ๋๋ฉด Follower๋ค์๊ฒ ๊ทธ ์ ๋ณด(notice)๋ฅผ ์ ๋ฌํ๋ ๊ฐ๋จํ ์์๋ฅผ ๋ง๋ค์ด๋ดค์ต๋๋ค. ๋จผ์ Blog ๊ฐ์ฒด์๋ notice ์์ฑ์ setter๊ฐ ๋์ํ๊ฒ ๋๋ฉด sendUpdateEvent ๋ฉ์๋๊ฐ ์คํ๋๊ฒ๋ ํด๋์์ต๋๋ค.
class Blog: Observable {
override val observers: ArrayList<Observer> = ArrayList()
var notice = ""
set(value) {
field = value
sendUpdateEvent()
}
}
Blog์ Follower๋ update๊ฐ ์คํ๋ ๋ ์ ๋ฌ๋ฐ์ notice(์ ๋ณด)๋ฅผ ์ฝ์์ ์ฐ๊ฒ ๋ฉ๋๋ค.
class Follower(private val id: String, private var blog: Blog): Observer {
override fun update() {
println("ID: [$id], NOTICE: [${blog.notice}]")
}
}
์์์ ๊ตฌํํ Blog์ Follower๋ฅผ ์ค์ ๋ก ์ฌ์ฉํ๊ฒ ๋๋ค๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
fun main() {
val blog = Blog()
blog.add(Follower("Kotlin", blog))
blog.add(Follower("Observer", blog))
blog.notice = "PATTERN"
}
// console
// ID: [Kotlin], NOTICE: [PATTERN]
// ID: [Observer], NOTICE: [PATTERN]
delegates
Delegated๋ Kotlin์ ๋ด์ฅ๋ ๊ฐ์ฒด์ ๋๋ค. ๊ทธ์ค์์๋ Observable ์์ฑ(์ด๋ฆ๋ง ๋ค์ด๋ Observer ํจํด๊ณผ ๊ด๋ จ์ด ์์ ๊ฒ ๊ฐ์)์ ํ์ฉํ ๊ตฌํ์ ๋๋ค.
Delegates์ observable์ ์ฃผ์ด์ง ์์ฑ์ด ์ฝ์ด์ง๊ฑฐ๋ ์์ ์ด ์๊ฒผ์ ๋ ์คํ๋๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์ฝ๋ฐฑ ํจ์์๋ property์ oldValue, newValue๊ฐ ์ฃผ์ด์ ธ์ ๋ค์ํ ์์ ์ด ๊ฐ๋ฅํด ๋ณด์ ๋๋ค. ์์ ์์๋ newValue๋ง ์ฌ์ฉํ์ต๋๋ค.
class Blog {
val followers = mutableListOf<(String) -> Unit>()
var notice: String by Delegates.observable("") { property, oldValue, newValue ->
followers.forEach { it(newValue) }
}
}
๋๋ค์์ ํ์ฉํด์ follwer๋ฅผ ๋ฑ๋กํ๋ ๋ชจ์ต์ ๋๋ค. ๋ฑ๋ก๋ follower๋ค์ notice๊ฐ ๋ณ๊ฒฝ์ด ์ผ์ด๋๋ฉด ์ฝ์์ ๊ทธ ์ ๋ณด๋ฅผ ์ฐ์ด์ค ๊ฒ์ ๋๋ค.
fun main() {
val blog = Blog()
blog.followers.add { notice ->
println("NOTICE: [$notice]")
}
blog.notice = "delegates"
}
// console
// NOTICE: [delegates]
์ ์ฒด ์์ค ์ฝ๋๋ ์ด๊ณณ์์ ํ์ธ ๊ฐ๋ฅํ์ญ๋๋ค.
์ฃผ์ ๋ฆฌ์ฃผ์ ๋ฆฌ
์ ๊ฐ ๊ฐ์ธ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์ ๋ ๋ฒ ์ ๋ ์ฌ์ฉํ๋ ํจํด์ ๋๋ค. ์๋นํ ์ ์ฉํ๋๋ผ๊ณ ์. ๊ทธ๋ฆฌ๊ณ ์ด๋ฒ์ ๊ธ์ ์์ฑํ๋ฉด์ ์์๋ณด๋ ๋น์ทํ์ง๋ง ๋ค๋ฅธ Publisher-Subscriber(๋ฐํ-๊ตฌ๋ ) ํจํด์ด ์๋ค์. ๊ณต๋ถ๋ฅผ ํ ์๋ก ๋ชจ๋ฅด๋ ๊ฒ ๋ ๋ง์ด ์๊ธฐ๋ ์ด์ํ ์ฝ๋ฉ ๊ณต๋ถ. ์ค๋์ ์ฌ๊ธฐ๊น์ง์ ๋๋ค. ๊ฐ์ฌํฉ๋๋ค.
'๐งฉDesign Patterns' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Design Patterns]Factory pattern, ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด๋ด๋ (0) | 2022.07.04 |
---|
๋๊ธ