수제녹차 2019. 9. 7. 19:44
728x90
반응형

- 옵저버 패턴

비유 : 신문사와 정기구독자

중요한 일이 일어났을 때 객체들에게 새소식을 알려준다.

객체들은 계속해서 정보를 받을지 여부를 실행중에 결정할 수 있다.

한 객체(주제)의 상태가 바뀌면 그 객체에 의존하는 다른 객체들(옵저버)한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다 의존성을 정의한다.  

데이터의 주인은 주제

 

ex. 기상 모니터링 애플리케이션

3가지 구성 요소 : 기상 스테이션(실제 기상 정보를 수집하는 장비)

WeatherData 객체(기상 스테이션으로부터 오는 데이터를 추적하는 객체)

현재 기상 조건을 보여주는 기상 디스플레이

 

- 구현

Subject의 인터페이스(registerObserver, removeObserver, notifyObservers),

Observer의 인터페이스(update)

각각의 구상 클래스

 

옵저버들이 모두 똑같은 인터페이스를 구현해야만 주제에서 데이터를 보내줄 수 있다.

 

- 옵저버 패턴의 특징

1) 바뀌는 부분을 찾아내서 바뀌지 않는 부분으로부터 분리시킨다.

옵저버 패턴에서 변하는 것은 주제의 상태와 옵저버의 개수, 형식이다.

옵저버 패턴에서는 주제를 바꾸지 않고도 주제의 상태에 의존하는 객체들을 바꿀 수 있다. 나중에 바뀔 것에 대비할 수 있다. 

 

2) 특정 구현이 아닌 인터페이스에 맞춰서 프로그래밍한다.

Subject와 Observer에서 모두 인터페이스를 사용한다.

Subject에서는 Subject 인터페이스를 통해서 Observer 인터페이스를 구현하는 객체들의 등록/탈퇴를 관리하고 그런 객체들한테 연락을 돌린다. 결합을 느슨하게 만든다.

3) 구성을 활용

주제와 옵저버 사이의 관계는 상속이 아니라 구성에 의해서 이루어진다.

실행중에 구성된다.

 

- 느슨한 결합(Loose coupling)

주제와 옵저버가 느슨하게 결합되어 있다.

그 둘이 상호작용을 하긴 하지만 서로에 대해 서로 잘 모른다.

주제가 옵저버에 대해 아는 것은 옵저버가 특정 인터페이스를 구현한다는 것 뿐

 

- ex.

package observer;

import java.util.ArrayList;

public class WeatherData implements Subject {
	private ArrayList observers;
	private float temperature;
	private float humidity;
	private float pressure;
	
	
	
	public WeatherData() {
		observers = new ArrayList();
	}
	
	public void registerObserver(Observer o) {
		observers.add(o);
	}
	
	public void removeObserver(Observer o) {
		int i = observers.indexOf(o);
		if (i >= 0) {
			observers.remove(o);
		}
	}

	public void notifyObservers() {
		for (int i=0;i<observers.size();i++) {
			Observer observer = (Observer) observers.get(i);
			observer.update(temperature,  humidity,  pressure);
		}
	}
	
	public void measurementsChanged() {
		notifyObservers();
	}
	
	public void setMeasurements(float temperature, float humidity, float pressure) {
		this.temperature= temperature;
		this.humidity = humidity;
		this.pressure = pressure;
		measurementsChanged();
	}
}
package observer;

public class CurrentConditionsDisplay implements Observer, DisplayElement {
	private float temperature;
	private float humidity;
	private Subject weatherData;
	
	public CurrentConditionsDisplay(Subject 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("Current conditions : " + temperature
				+ "F degrees and " + humidity + "% humidity");
	}
}

출처 : HeadFirst Design Patterns

반응형