옵저버 패턴은 신문사와 정기구독자로 이루어지는 신문 구독 서비스에 비유해서 생각하면 됩니다.
하지만 보통 옵저버 패턴은 다음과 같은 식으로 정의됩니다.
옵저버 패턴(Observer Pattern)에서는 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many) 의존성 을 정의합니다.
일대다 관계는 주제와 옵저버에 의해 정의됩니다. 옵저버는 주제에 의존합니다.
주제의 상태가 바뀌면 옵저버한테 연락이 가지요.
연락 방법에 따라 옵저버에 있는 값이
새로운 값으로 갱신될 수도 있습니다.
옵저버 패턴을 구현하는 방법에는 여러 가지가 있지만,
대부분 주제(Subject)인터페이스와
옵저버(Observer)인터페이스가 들어있는 클래스 디자인을 바탕으로 합니다.
한번 직접 살펴보죠.
public interface Subject{ public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyObservers(); } public interface Observer{ public void update(float temp, float humidity, float pressure); } public interface DisplayElement{ public void display(); }
public class WeatherData implements Suject{ 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 removerObserver(Observer o){ int i = observers.indexOf(o); if(i>=0){ observers.remove(i); } } public void notifyObservers(){ for(int i=0; i<observers.size(); i++){ Observer observer = (Observer) observers.get(i); observer.update(temperature, humidity, pressure); } } public void measurementChanged(){ notifiyObservers(); } public void setMeasurements(float temperature, float humidity, float pressure){ this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); } //기타 WeatherData 메소드 }
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"); } }
public class WeatherStation{ public static void main(String[] args){ WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData); ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData); weatherData.setMeasurements(80, 65, 30.4f); weatherData.setMeasurements(82, 70, 29.2f); weatherData.setMeasurements(78, 90, 29.2f); } }