February
19th,
2025
옵저버 패턴 (Observer Pattern)
문제
신제품이 출시되었다는 소식을 고객에게 알려야할 때 관심없는 사용자에게 까지 알림을 가는 것은 과할 수 있다. 해당 카테고리에 관심있는 사람만 알림을 받게 해야한다.
해결
주기적으로 신제품을 출시하는 주체를 subject라고 한다. 그리고 이 신제품에 관한 소식을 구독할 수 있는 subscriber가 있다. subscriber는 언제든 subject를 구독하거나 구독취소할 수있다. 이제 중요한 이벤트가 발생할 때 마다 subscriber리스트를 참조하고 그들에게 특정 알림 메서드를 호출한다.
구조
- publisher는 다른 객체들에게 이벤트를 발행한다.
- 새 이벤트가 발생하면 publisher는 subscriber 리스트를 보고 알람을 보낸다
- subscriber 인터페이스는 알림 인터페이스를 선언하며 대부분 단일 update 메서드로 구성된다
- 구상 subscriber는 publisher가 보낸 알림들ㅇ에 대한 응답으로 몇가지 작업을 수행한다
- 일반적으로 subscriber 업데이트를 올바르게 처리하기 위해 컨텍스트 정보가 어느정도 필요하다. 그러므로 context 데이터를 알림 메서드의 인수들로 전달한다
- 클라이언트는 publisher는 subscriber들은 별도로 생성한 후 subscriber들은 publisher 업데이트에 등록한다
예시
interface Listener {
fun update(val filename: String)
}
class LoggingListener: Listener {
override fun update(val filename: String) {
println("logging ${filename}")
}
}
class Publisher {
private var listenerList: List<Listener> = arrayList()
fun subscribe(listener: Listener) {
listenerList.add(listener)
}
fun unscribe(listener: Listener) {
listenerList.remove(listener)
}
fun notify(data: String) {
listenerList.forEach {listener -> listener.update(data)}
}
}
fun main() {
val publisher = Publisher()
val listener = LoggingListener()
publisher.subscribe(listener)
publisher.notify("Hello")
}
적용
- 한 객체의 상태가 변경되어 다른 객체들이 변경되어야할 때
- 이 패턴은 앱의 일부 객체들이 제한된 시간 동안 또는 특정 경우에만 다른객체들을 관찰해야 할 때 사용
장단점
- 개방폐쇄원칙
- 런타임에 객체 간의 관계들을 형성할 수 있다
- 구독자들은 무작위로 알림을 받는다