[디자인 패턴(Design Pattern)] 옵저버(Observer)
카테고리: DesignPattern
태그: 디자인 패턴
옵저버 패턴이란?
옵저버 패턴이란 행위 패턴 중의 하나로 객체의 상태 변화를 관찰하는 옵저버 목록을 객체에 등록해 상태 변화가 있을 때 마다 객체가 자신을 관찰하는 옵저버들에게 변화를 통지하는 디자인 패턴이다.
장점
- 실시간으로 객체의 상태 변화를 전파할 수 있다.
- 객체간의 의존성을 제거할 수 있다.
옵저버 패턴을 너무 많이 사용할 경우 상태 관리가 힘들 수 있음과 데이터 배분 문제를 고려해야한다.
구성
이미지 출처 : 위키피디아
- Subject : 이벤트를 발생시키는 주체, 관찰의 대상인 객체
- Observer : 관찰자, 관찰 대상인 객체가 발생시키는 이벤트를 처리
간단한 예시 (Kotlin)
옵저버 패턴은 보통 Listener의 형태로 이벤트 핸들링 시스템을 구현하는 데 사용된다. 우리는 간단하게 작동원리를 알 수 있는 예시를 작성해 보자.
우선 Observer의 인터페이스를 정의한다.
interface Observer {
fun notify() : Boolean
}
이제 관리 대상이될 객체의 인터페이스를 정의하자
interface Subject {
fun registerObserver(observer: Observer)
fun unregisterObserver(observer: Observer)
fun notifyObservers()
}
Observer 인터페이스를 상속받는 ObserverA와 ObserverB를 만든다.
class ObserverA : Observer {
override fun notify() : Boolean{
println("ObserverA action")
return true
}
}
class ObserverB : Observer {
override fun notify(): Boolean {
println("ObserverB action")
return false
}
}
딱히 별 기능은 없다. 옵저버에서 이벤트에 대한 처리가 일어남을 나타낸다.
이제 관찰의 대상이될 SubjectA 클래스를 만들어보자 앞서 만들었던 Subject의 인터페이스를 따른다.
class SubjectA : Subject {
private val observerCollection = mutableListOf<Observer>()
var num = 0
override fun registerObserver(observer: Observer) {
observerCollection.add(observer)
}
override fun unregisterObserver(observer: Observer) {
observerCollection.remove(observer)
}
override fun notifyObservers() {
observerCollection.forEach {
it.notify()
}
}
}
notifyObservers()
메소드를 호출 하는 것으로 해당 객체를 관찰하는 모든 Observer에게 이벤트를 통지할 수 있다. 물론 조건문 등을 이용해 특정 Observer에게만 이벤트를 통지하는 것도 가능하다.
다음 코드를 통해 Observer가 잘 작동하는지 확인해보자
fun main() {
val subjectA = SubjectA()
subjectA.registerObserver(ObserverA())
subjectA.registerObserver(ObserverB())
repeat(5){
println("num : ${subjectA.num++}")
subjectA.notifyObservers()
println()
}
}
출력
num : 0
ObserverA action
ObserverB action
num : 1
ObserverA action
ObserverB action
num : 2
ObserverA action
ObserverB action
num : 3
ObserverA action
ObserverB action
num : 4
ObserverA action
ObserverB action