Observer Pattern
View all Design Patterns
객체 간 1:N 관계를 맺어 하나의 객체(1)에 변경이 생겼을 때, 이에 의존하는 객체들(N)이 알림을 받고 자동으로 갱신되는 방법이다. 주로 분산 이벤트 처리 시스템에서 이벤트를 생성하는 컴포넌트와 이러한 이벤트에 반응하는 컴포넌트 사이의 느슨한 결합을 제공하기 위해 사용된다.
Class Diagram
Abstract overview
Concrete example
Code
interface Subject {
subscribe(observer: Observer): void;
unsubscribe(observer: Observer): void;
notifyObservers(): void;
getState(): number;
setState(state: number): void;
}
interface Observer {
update(subject: Subject): void;
}
class ConcreteSubject implements Subject {
private state: number = 0;
private observers: Observer[];
constructor() {
this.observers = [];
}
getState(): number {
return this.state;
}
setState(state: number): void {
this.state = state;
this.notifyObservers();
}
subscribe(observer: Observer): void {
const isExist = this.observers.includes(observer);
if (isExist) {
console.log("Observer has been already attached.");
return;
}
this.observers.push(observer);
}
unsubscribe(observer: Observer): void {
const observerIndex = this.observers.indexOf(observer);
if (observerIndex === -1) {
console.log("Observer not found.");
return;
}
this.observers.splice(observerIndex, 1);
}
notifyObservers(): void {
for (const observer of this.observers) {
observer.update(this);
}
}
}
class ConcreteObserver implements Observer {
/** 상태 갱신 */
update(subject: Subject): void {
console.log(
"ConcreteObserver: Event triggered. State:",
subject.getState()
);
}
}
const concreteSubject = new ConcreteSubject();
const observerA = new ConcreteObserver();
const observerB = new ConcreteObserver();
concreteSubject.subscribe(observerA);
concreteSubject.subscribe(observerB);
concreteSubject.setState(10);
// ConcreteObserver: Event triggered. State: 10
// ConcreteObserver: Event triggered. State: 10
setState
함수로 상태를 변화하게 되면, this.notifyObservers()
코드가 실행되면서 로그가 출력되게 된다.
Pros and Cons
Pros
Subject
와Observer
간의 느슨한 결합으로, 서로 독립적으로 존재하며, 따라서 서로 간의 의존성이 낮다.- 새로운 옵저버를 추가하는 것이 간단하다.
- 런타임에 동적으로 옵저버를 추가하거나 제거할 수 있다.
Cons
- 옵저버가 올바르게 해제되지 않으면, 가비지 컬렉터가 메모리를 회수하지 못해 메모리 릭(Leak)이 발생할 수 있다.
- 멀티 스레드 환경에서 동기 화 문제(경쟁 상태 또는 데드락)가 발생할 수 있다.
- 두 개 이상의 스레드가 동시에
Subject
의 상태를 변경하거나,Observers
목록을 수정할 때, 데이터가 일관되지 않은 상태가 될 수 있다.
- 두 개 이상의 스레드가 동시에