caffeine-library / Domain-Driven-Design

🌱 에릭 에반스의 '도메인 주도 설계'를 읽는 스터디
4 stars 0 forks source link

[question] 옵저버 패턴 #22

Closed emiling closed 1 year ago

emiling commented 1 year ago

질문

하위 계층의 객체가 상위 수준의 객체와 소통하기 위한 방법으로 옵저버 패턴을 얘기하고 있는데요, 한 번 언급된 김에 정리하고 가면 좋을 것 같습니다.

배경

연관 챕터

https://github.com/caffeine-library/Domain-Driven-Design/issues/19

emiling commented 1 year ago

Observer Pattern

객체의 상태 변화를 관찰하여 변화가 발생하면 변화를 통지받고 자동으로 갱신될 수 있게 한다.

image

구현

interface Observer {
    fun update(message: String)
}

class Insight: Observer {
    override fun update(message: String) {
        println(message)
    }
}

class NewYorkTimes: Observer {
    override fun update(message: String) {
        if(message.contains("money")) println("Breaking news from Insight! $message")
    }
}

class Guardian: Observer {
    override fun update(message: String) {
        if(message.contains("queen")) println("Yet more news in London... $message")
    }
}
interface Subject {
    fun attach(o: Observer)
    fun detach(o: Observer)
    fun notify(message: String)
}

class TweetFeed: Subject {
    private val observers: MutableList<Observer> = mutableListOf()
    override fun attach(o: Observer) { observers.add(o) }
    override fun detach(o: Observer) { observers.removeIf { it == o } }
    override fun notify(message: String) { observers.forEach { it.update(message) } }
}

실행

val musk = TweetFeed();

// register observers 
musk.attach(Insight())
musk.attach(NewYorkTimes())
musk.attach(Guardian())

// notify event
musk.notify("Even though Startlink is still losing money & other companies are getting billlions of taxpayer $, we'll just keep funding Ukraine govt for free")
musk.notify("Doge")

예시

https://docs.spring.io/spring-framework/docs/5.3.7/reference/html/core.html#context-functionality-events

Spring ApplicationContext 이벤트 핸들링 시에 ApplicationListener 인터페이스를 구현한 bean이 컨텍스트에 배포되면 ApplicationEvent가 ApplicationContext에 발행될 때마다 해당 bean으로 알람 전송

Event handling in the ApplicationContext is provided through the ApplicationEvent class and the ApplicationListener interface. If a bean that implements the ApplicationListener interface is deployed into the context, every time an ApplicationEvent gets published to the ApplicationContext, that bean is notified. Essentially, this is the standard Observer design pattern.

kth990303 commented 1 year ago

프록시 패턴 vs 옵저버 패턴

프록시 패턴: 대리자 역할, 부수 로직 첨가 및 묶어서 한번에 가능 옵저퍼 패턴: 하위 객체가 타 객체 또는 상위 객체한테 메서드 호출 및 전달