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>

옵저버 패턴은 보통 주제 인터페이스와 옵저버 인터페이스가 들어있는 클래스 디자인으로 구현한다.

Untitled

옵저버는 데이터가 변경되었을 때 주제에서 갱신해 주기를 기다리는 입장이기에 의존성을 가진다.

이런 방법을 사용하면 여러 객체가 동일한 데이터를 제어하는 방법보다 더 깔끔한 객체지향 디자인을 만들 수 있다.

느슨한 결합

  • 객체들이 상호작용 할 수는 있지만, 서로를 잘 모르는 관계를 의미한다.

  • 느슨한 결합을 활용하면 유연성이 아주 좋아진다.

<aside> 💡 디자인 원칙 상호작용하는 객체 사이에는 가능하면 느슨한 결합을 사용해야 한다.

</aside>

Untitled

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