옵저버 패턴 (Observer Pattern)
-
- 객체의 상태 변화(Subject)를 감지하고, 그 변화에 반응해야하는 다수의 객체(Observer)에 이를 자동으로 통보하는 디자인 패턴
- 즉, 하나의 객체(Subject)가 변할때 연결된 다른 객체들(Observer)에게 자동으로 변화가 통지 되고 동작하도록 설계한것
전략 패턴의 핵심
-
- Subject
- 상태를 관리하면 상태변화가 발생하면 옵저버들에게 이를 알린다.
- Observer
- Subject를 구독하여 상태변화를 감지하고 알림을 받으면 특정 작업을 수행
- 객체간 느슨한결합(loose coupling)을 유지하면서도 상태 변경에 따른 반응을 자동화한다.
- Subject
구성요소
-
- Subject
- 관찰되는 객체로, 상태를 관리하며, 옵저버들을 등록/제거하고 상태 변화시 통보
- Observer
- Subject를 관찰하는 객체로 Subject의 상태 변화에 반응
- Observer list
- Subject는 자신의 상태를 감시하고 있는 옵저버들의 목록
- Subject
예제 - 뉴스 구독
// Subject (주체)
class NewsPublisher {
constructor() {
this.observers = []; // 옵저버 목록
}
subscribe(observer) {
this.observers.push(observer); // 옵저버 등록 //this.observers 배열에 옵저버를 추가
}
unsubscribe(observer) {
this.observers = this.observers.filter((obs) => obs !== observer); // 옵저버 제거 // filter 메서드를 사용하여 옵저버 목록에서 해당 옵저버를 제거
}
notify(news) {
this.observers.forEach((observer) => observer.update(news)); // 배열의 옵저버들에게 알림 // 각 옵저버의 update(news) 메서드를 호출
}
}
// Observer (옵저버)
class Subscriber {
constructor(name) {
this.name = name;
}
update(news) {
console.log(`${this.name} received news: ${news}`); //Subject로부터 전달된 뉴스(알림)를 받아 실행
}
}
// 클라이언트 코드
const publisher = new NewsPublisher(); // publisher는 NewsPublisher의 인스턴스(주체)
//subscriber1과 subscriber2는 각각 Subscriber의 인스턴스(옵저버)
const subscriber1 = new Subscriber("Alice");
const subscriber2 = new Subscriber("Bob");
// 옵저버 등록
publisher.subscribe(subscriber1);
publisher.subscribe(subscriber2);
//publisher는 두 옵저버(subscriber1, subscriber2)에게 상태 변화를 통보할 준비 완료
// 뉴스 발행
publisher.notify("Breaking News: Observer Pattern Explained!"); //notify 호출 -> 등록된 모든 옵저버의 update(news)매서드 실행
//실행결과
//Alice received news: Breaking News: Observer Pattern Explained!
//Bob received news: Breaking News: Observer Pattern Explained!
// 옵저버 제거 후 뉴스 발행
publisher.unsubscribe(subscriber1);
publisher.notify("More News: Observer Pattern in JavaScript!");
//실행결과
//Bob received news: More News: Observer Pattern in JavaScript!
작동 방식
- NewsPublisher (Subject):
- 옵저버(구독자) 목록을 관리하며, 상태 변화(뉴스 발행)가 발생하면 구독자들에게 알림을 보낸다.
- subscribe(observer): 옵저버를 등록.
- unsubscribe(observer): 옵저버를 제거.
- notify(news): 모든 등록된 옵저버들에게 상태 변화(뉴스)를 알린다.
- Subscriber (Observer):
- 뉴스 발행 시 Subject로부터 알림을 받고, update(news) 메서드를 통해 해당 알림을 처리
- 클라이언트 코드:
- Subject와 Observer 간의 관계를 설정.
- Subject의 상태가 변경될 때, Observer는 자동으로 알림을 받고 반응.
옵저버 패턴의 장점
- 느슨한 결합(Loose Coupling):
- Subject와 Observer 간의 의존성이 낮습니다.
- Subject는 자신의 상태를 알리기만 하고, Observer가 어떤 작업을 수행하는지 알 필요가 없다.
- 자동 알림:
- Subject의 상태 변화가 자동으로 Observer에 통지되므로, 수동으로 상태를 확인하거나 데이터를 동기화할 필요가 없다.
- 확장성:
- 새로운 Observer를 추가하거나 제거해도 Subject의 코드에는 영향을 미치지 않는다.
옵저버 패턴의 단점
- 성능 문제:
- 옵저버의 수가 많아지면, 상태 변화 시 모든 옵저버에게 알림을 보내는 비용이 증가할 수 있다.
- 디버깅 어려움:
- Subject와 Observer 간의 상호작용이 복잡해질수록 디버깅과 테스트가 어려워질 수 있다.
- 예상치 못한 동작:
- Observer가 Subject의 상태 변화에 대해 적절히 반응하지 않으면, 예상치 못한 결과를 초래할 수 있다.
옵저버 패턴이 적합한 상황
- 상태 변화와 관련된 동작이 여러 객체에 영향을 미칠 때:
- 예: GUI 이벤트 시스템, 알림 시스템.
- 여러 객체가 동일한 데이터를 참조하거나 동기화해야 할 때:
- 예: 데이터 모델과 UI 간의 동기화.
- 런타임에 객체 간의 의존 관계를 동적으로 변경해야 할 때:
- 예: 구독 기반 애플리케이션.
실제 응용 사례
- 이벤트 시스템:
- DOM 이벤트 리스너(브라우저의 addEventListener).
- 데이터 동기화:
- 모델과 뷰 간 데이터 동기화(MVC 패턴).
- 알림 시스템:
- 이메일, 푸시 알림, SMS 등 여러 채널로 메시지를 전송.
- 퍼블리셔-서브스크라이버 시스템:
- Kafka, RabbitMQ 같은 메시지 큐 시스템.
'디자인패턴' 카테고리의 다른 글
디자인패턴 - 이터레이터 패턴 (0) | 2024.12.17 |
---|---|
프록시패턴 (Proxy Pattern) (0) | 2024.12.15 |
디자인패턴 - 전략패턴 (2) | 2024.12.14 |
디자인패턴 - 팩토리 패턴 (0) | 2024.12.12 |
디자인 패턴 - 싱글톤 패턴 (0) | 2024.12.12 |