
한
객체(주제)의 상태가 바뀌면, 그 객체에 의존하는 다른객체(옵저버)에게 연락이 가고, 자동으로 내용이 갱신되는 방식을 사용하는 패턴
발행자(Publisher) - 구독자(Subscriber) 관계로 설명하기도 한다.
일대다(1:N) 의존성
| 설명 | |
|---|---|
| 문제 | 옵저버 객체는 주제 객체의 상태 변화나 이벤트에 관심을 가지며, 이벤트를 생성 시키면 이벤트에 대해서 자신의 고유한 방식으로 반응을 해야한다. |
| 해결책 | 주제와 옵저버 인터페이스를 정의하고, 옵저버 객체는 이 인터페이스를 구현한다. 주제 객체는 옵저버 객체를 동적으로 등록하고, 등록된 모든 객체에게 통보할 수 있다. |
옵저버 패턴을 사용하지 않고, 이벤트 발생 시 객체에 값이나 이벤트를 넘겨주면 되는거 아니야? 라고 생각 할 수 있다.
실제로 그러한 방식으로 코드를 작성해도, 실행 중 문제는 딱히 없다.<
그러나, 이벤트를 체크해야 하는 오브젝트들이 존재할 경우 해당 이벤트가 발생하는지 주기적으로 확인 해 줘야 한다.(폴링) → CPU 자원 낭비
느슨한 결합(Loose Coupling) : 객체 간 상호작용은 가능하나, 서로를 잘 모르는 관계
먼저, 기본적인 옵저버 패턴의 UML 형태이다.

다음은 옵저버 패턴의 예제로 자주 나오는 기상스테이션 UML이다.
개인 공부이므로 세부 속성들은 다소 생략하였음

먼저 주제 객체의 인터페이스와 옵저버 객체의 인터페이스를 정의한다
주제(Subject) 인터페이스
registerObserver(Observer o): 옵저버를 등록
removeObserver(Observer o): 옵저버를 제거
notifyObservers(): 모든 등록된 옵저버들에게 주제의 상태 변화에 대해 알림
옵저버(Observer) 인터페이스
update() : 주제의 상태 변화가 있을 때 옵저버에서 실행되는 메서드
💡 ※ 옵저버 클래스는 주제 객체와 연관 관계에 있다.
→ 옵저버 등록 메서드는 옵저버의 생성자에서 호출되지만, 실제 등록은 주제 객체에서 수행됨 (옵저버 클래스 내에서 Subject.registerObserver(this); 형태로 수행)

💡 ※ 주제 객체는 옵저버 리스트와 연관 관계에 있다.
→ 주제 객체는 상태 변화 시, 등록된 모든 옵저버에게 상태 변화를알려야 하기 때문!!

💡 ※ notify() 호출 시의 옵저버 객체
→ notify() 호출 시, 모든 옵저버 객체의 update(인터페이스)를 실행하게 되는데, 해당 인터페이스는 옵저버 별로 필요한 작업을 구현한 것이다

각 옵저버가 수행해야 할 update를 구현 하고, 옵저버 등록까지 마쳤으면 옵저버 패턴의 적용이 끝난 것 이다.
그러면 setMeasureMents를 통해 weather의 값이 변경되면, weather(주제)를 관찰하고 있는 모든 Observer들에게 notify(); 가 수행된다!
만약 주제 객체를 참조하는 새로운 클래스가 추가 된다면, 해당 옵저버는 인터페이스를 구현하고, 옵저버 등록만 하면 된다!
public static void main(String[] args) {
WeatherData weatherData = new WeatherData(); // 주제 객체
CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); // 상태 옵저버 등록
PressureDisplay pressureDisplay = new PressureDisplay(weatherData); // 기압 옵저버 등록
weatherData.setMeasurements(80, 65, 30.4f); // 이벤트 발생 1
weatherData.setMeasurements(70, 65, 30.4f); // 이벤트 발생 2
weatherData.setMeasurements(60, 65, 30.4f); // 이벤트 발생 3
weatherData.removeObserver(pressureDisplay); // 기압 옵저버 삭제
weatherData.setMeasurements(50, 65, 30.4f); // 이벤트 발생 4(상태 옵저버만 호출)
}
}

옵저버 패턴은 객체지향 설계에서 중요한 디자인 패턴이다.
객체 간의 결합도를 낮추고, 확장성을 높이며, 실시간 업데이트를 가능하게 한다.
주제 객체가 상태를 관리하고 변경을 통지하며, 옵저버 객체는 이러한 변경을 감지하고 자신의 상태를 갱신한다.
또한 동적으로 새로운 옵저버를 쉽게 추가, 삭제할 수 있어, 기능확장이 용이하다.
옵저버 패턴을 올바르게 적용하면, 코드의 재사용성과 유지보수성이 크게 향상되고, 시스템의 복잡성을 효과적으로 관리할 수 있다!
요약
옵저버 패턴은 주제의 상태 변화가 있을 때 옵저버들에게 자동으로 통지한다.