Observer 패턴이란?
객체 간의 일대다(1:N) 관계에서 한 객체의 상태가 변화할 때, 그 객체에 의존하는 다른 객체들이 알림을 받아 변화를 반영할 수 있게 하는 패턴
구독한 객체에게 이벤트가 발생할 때마다 관찰자가 알림을 받을 수 있다.
- Subject / Observable (주체) : 상태를 가지고 있으며, 관찰자에게 상태 변화를 통지하는 객체
- 관찰자 등록/제거 메서드 가짐 - subscribe(), unsubscribe()
- 상태가 변경되면 모든 관찰자에게 변화를 알림 - notify()
- Observer (관찰자) : 주체의 상태 변화를 수신하여 처리하는 객체
- 관찰 대상이 업데이트 되면 그에 반응하는 메서드 정의
Subject
객체를 정의했다. 관찰자들의 배열을 가지고, 관찰자 등록/제거/알림전송 3가지 메서드를 가진다.Button
, Switch
컴포넌트를 가진 App을 만들었다. 사용자가 버튼을 클릭하거나 스위치를 토글할 때마다 타임스탬프를 기록하고 토스트 알림을 화면에 노출할 것이다.Subject의
notify()
로부터 data를 받게 될 logger
, toastify
함수를 만들었다. 이 두 함수가 observer로써 작동하기 위해 subject
인스턴스를 생성하고 subscribe()
를 사용했다. 이제 이벤트가 발생할 때마다 두 함수는 토스트 알림을 받게된다.버튼 클릭
handleClick
, 스위치 토글 handleToggle
이벤트 핸들러를 만들고 그 안에서 nofify()
를 실행한다. 이렇게 이벤트가 발생하면 Subject의 notify
는 observer인 logger
, toastify
함수에게 data를 인자로 넘긴다.전체 플로우는 아래의 영상과 같다.
위 예제의 실행 결과는 다음과 같다.
활용예제
뉴스 구독 시스템
NewsSubject
: Subject 역할. 뉴스 주제
NewsSubscriber
: Observer 역할. 구독자
Observer가 함수가 아닌 사람인 경우! 더 직관적
예제 실행결과
Subscriber 1 received news: Breaking News: Observer Pattern in Action!
Subscriber 2 received news: Breaking News: Observer Pattern in Action!
Subscriber 2 received news: Another Update: Only Subscriber 2 receives this.
사례분석
RxJS : Observer 패턴을 구현한 유명 오픈소스 라이브러리
Reactive X는 Observer 패턴, 이터레이터 패턴, 함수형 프로그래밍을 조합하여 이벤트의 순서를 이상적으로 관리할 수 있다.
RxJS 를 사용하면 Subject를 따로 정의하지 않아도 Subject, Observer를 만들어낼 수 있다. 공식 문서의 예제로 사용자가 문서를 드래그 중인지 아닌지 콘솔에 출력해주는 것을 확인할 수 있다.
예제코드
장점
- 느슨한 결합 (Loose Coupling) : 주체와 관찰자가 직접적으로 서로를 참조하지 않고 순수하게 상태 변경에만 집중하면 된다. ⇒ 결합도가 낮아지고 유지보수가 쉬워진다
- 확장성 : 새로운 관찰자 추가 또는 제거가 간단하다.
- 실시간 업데이트 : 주체의 상태가 변경되어 실시간 데이터 업데이트가 필요한 경우에 유용하게 활용된다.
- 재사용성 : 주체와 관찰자가 각각 독립적으로 재사용 될 수 있다.
단점
- 성능 저하 : 관찰자가 많아지면 성능이 저하될 수 있다.