Observer 패턴
by EarlyHail
Observer
객체 사이에 일 대 다의 의존 관계를 정의해 두어, 어떤 객체의 상태가 변할 때 그 객체의 의존성을 가진 다른 객체들이 그 변화를 통지받고 자동으로 갱신될 수 있게 만든다.
감시자(observer)는 주체(subject)를 감시하며 주체에 일어난 변경을 통보받는다.
이러한 종류의 상호작용을 게시(publish)-구독(subscribe)관계 라고도 한다. 주체(subject)는 Observed로 표현되기도 한다.
-
Subject
Observer들을 알고있는 주체
Observer의 추가 / 삭제, notify 하는데 필요한 인터페이스를 제공한다.
-
ConcreteSubject
ConcreteObserver 객체에게 알려주어야 하는 상태를 저장한다.
상태가 변경될 때 감시자들에게 변경을 통보한다.
-
Observer
Subject에 생긴 변화에 관심 있는 객체들에게 필요한 인터페이스를 정의한다.
-
ConcreteObserver
Subject의 상태와 상태와 일관성을 유지해야하는 상태를 저장한다.
Subject와 해당 Observer의 상태를 일관되게 유지하는데 사용하는 갱신 인터페이스를 구현한다.
Observer 패턴 적용
-
Subject와 ConcreteSubject
interface Subject { state; attach: (observer: Observer) => void; detach: (observer: Observer) => void; notify: () => void; } class CurrentTimeModel implements Subject { private observers: Observer[] = []; public state: Date; attach(observer: Observer) { this.observers.push(observer); } detach(observer: Observer) { this.observers = this.observers.filter( (currentObserver) => currentObserver != observer ); } notify() { this.observers.forEach((observer) => observer.update(this)); } changeCurrentTimer() { this.state = new Date(); this.notify(); } }
Subject와 Subject를 구현하는 CurrentTimeModel(ConcreteSubject)이다.
CurrentTimeModel Observer 패턴의 정의에 따라 attach, detach, notify를 구현하였고
changeCurrentTimer
는 CurrentTimeModel의 상태를 변경한 뒤 notify 함수를 호출하여 observer에게 상태의 변화를 알려준다. -
Observer와 ConcreteObserver
interface Observer { update: (subject: Subject) => void; } class DigitalClock implements Observer { update(subject: Subject) { console.log(subject.state); } }
Observer와 Observer를 구현하는 DigitalClock(ConcreteObject)이다.
update
는 CurrentTimeModel의 객체를 전달받아 state를 참조하는 방식으로 Subject의 상태 변화를 감지하여 동작할 수 있다. -
사용
const clockTimer = new ClockTimer(); const digitalClock1 = new DigitalClock(); const digitalClock2 = new DigitalClock(); clockTimer.attach(digitalClock1); clockTimer.attach(digitalClock2); clockTimer.changeCurrentTimer();
Observer 패턴은 Vanilla JS에서 Frontend 개발할 때, Subject를 모델로 삼고 모델에 저장할 데이터에 의존성이 있는 객체들을 Observer로 두어 개발했던 경험이 있다.
Frontend에서 간단하게 데이터를 상태로 관리할 좋은 패턴이라고 생각한다.