Ch2. 옵저버 패턴 : 객체들에게 연락 돌리기
기상 모니터링 애플리케이션 만들어보기
요건
기상 스테이션 (실제 기상 정보를 수집하는 물리 장비)
WeatherData 객체 (기상 스테이션으로부터 오는 정보를 추적하는 객체)
사용자에게 현재 기상 조건을 보여주는 디스플레이 객체
weatherData 가 각각 온도, 습도, 기압의 getter 메서드를 가지고 있을 때 변경때마다 디스플레이를 업데이트하는 메서드를 작성해보자.
Step1.
public class Weather Data {
// 인스턴스 변수 선언
public void measurementsChanged() {
float temp = getTemperature();
float humidity = getHumidity();
float pressure = getPressure();
currentConditionsDisplay.update(temp, humidity, pressure);
statisticsDisplay.update(temp, humidity, pressure);
forecastDisplay.update(temp, humidity, pressure);
}
}
⇒ 아래 업데이트 시, 구체적인 구현에 맞춰 코딩했으므로 프로그램을 고치지 않고는 다른 디스플레이 항목을 추가하거나 제거할 수 없다. 또, 아래 부분 바뀔 수 있는 부분이므로 캡슐화해야한다.
옵저버 패턴
신문사(subject) + 구독자(observer) = 옵저버 패턴
주제객체 → 옵저버 객체
주제에서 중요한 데이터를 관리한다. 주제 데이터가 바뀌면 옵저버에게 그 소식이 전해진다.
<aside> 💡 옵저버 패턴(Observer Pattern)은 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체에게 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many) 의존성을 정의한다.
</aside>
옵저버 패턴은 보통 주제 인터페이스와 옵저버 인터페이스가 들어있는 클래스 디자인으로 구현한다.

옵저버는 데이터가 변경되었을 때 주제에서 갱신해 주기를 기다리는 입장이기에 의존성을 가진다.
이런 방법을 사용하면 여러 객체가 동일한 데이터를 제어하는 방법보다 더 깔끔한 객체지향 디자인을 만들 수 있다.
느슨한 결합
객체들이 상호작용 할 수는 있지만, 서로를 잘 모르는 관계를 의미한다.
느슨한 결합을 활용하면 유연성이 아주 좋아진다.
<aside> 💡 디자인 원칙 상호작용하는 객체 사이에는 가능하면 느슨한 결합을 사용해야 한다.
</aside>

Subject Interface 구현하기
public class WeatherData implements Subject {
private List<Observer> observers;
private float temperature;
private float humidity;
private float pressure;
public weatherData() {
observers = new ArrayList<Observer>();
}
public void registerObserver(Observer o) {
observers.add(o);
}
public void removeObserver(Oberserver o) {
observers.remove(o);
}
public void notifyObservers() {
for(Observer observer : observers) {
observer.update(temperature, humidity, pressure);
}
}
public void measurementsChanged() {
notifyObservers();
}
}
디스플레이 요소 구현하기
public class CurrentConditionsDisplay implements Observer, DisplayElement {
private float temperature;
private float humidity;
private WeatherData weatherData;
public CurrentConditionsDisplay(WeatherData weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
display();
}
public void display() {
System.out.println("현재 상태 : 온도 " + temperature + "F, 습도 " + humidity + "%");
}
}
라이브러리 속 옵저버 패턴 알아보기
JDK에 있는 자바빈(Java Bean)과 스위(Swing)
풀 방식으로 코드 바꾸기
옵저버가 필요한 데이터를 골라서 가져가도록 하는 방법이 더 좋다.
Last updated