The observer pattern

2023. 10. 19. 16:02디자인패턴

728x90

배경

 

weather station software을 사와서 weather monitoring app을 만들려 한다.

 

새로운 기기를 만들때마다 계속 추가해야함.

 

 

해결방안

subject 객체가 관리 

새로운 기기가 등록을 요청하면 등록시켜주고

기가가 삭제를 요청하면 내보내고

등록된 기기들에만 정보를 보내준다.

이것이 Observer Pattern이다.

->  일대다로  정의하여 subject object가 상태를 변경하면

subject object에 속해있는 모든 observer들이 알림을 받고 자동으로 업데이트되도록 한다.

 

 

디자인 원칙: 상호작용해야하는 객체 사이엔 종속관계가 약해야한다.

 

public interface Subject{
	public void registerObserver(Observer o); //기기 등록
	public void removeObserver(Observer o); //기기 제거
	public void notifyObserver(); //기기들에게 알림 발송
}

public interface Observer{
	public void update(float temp, float humidity, float pressure); //받아온 정보로 자신을 업데이트
}

public interface DisplayElement{
	public void display(); //온도,습도,기압 출력
}

 

public class WeatherData implements Subject{
	private ArrayList observers; //observer들을 보관할 배열
    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); //해당 observer가 저장된 배열의 인덱스 번호
        if(i>=0){
        	observers.remove(i); //삭제
        }
    }
    public void notifyObservers(){
    	for(int i=0;i<observers.size();i++){
        	Observer observe=(Observer) observers.get(i);
            observer.update(temperature,humidity,pressure);
        }
    }
    public void measurementsChanged(){ //기상정보가 업데이트되면 observer들에게 알림
    	notifyObservers();
    }
    
   public void setMeasurements(float temperature, float humidity, float pressure){
   //기상정보 세팅
   	this.temperature=temperature;
    this.humidity=humidity;
    this.pressure=pressure;
    measurementsChanged() 
    }
}
public class CurrentConditionsDisplay implements Observer, DisplayElement {
    private float temperature;
    private float humidity;
    private Subject weatherData;
    
    public CurrentConditionsDisplay(Subject weatherData) { //생성자.Subject에 자신을 등록시킴
        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(); //Subject 생성
        /*기기들 등록*/
        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);
    }
}

 

자바에 observer pattern 기능을 하는 내장함수가 있다.

subject는 observable이고

observer는 observer이다.

그러나 다른점은 observable이 class라는 점이다.

따라서 extend로 상속받아야 한다.

import java.util.Observable;
import java.util.Observer;
public class WeatherData extends Observable {
    private float temperature;
    private float humidity;
    private float pressure;
    public WeatherData() { }
    public void measurementsChanged() {
        setChanged();
        notifyObservers();
    }
    public void setMeasurements(float temperature, float humidity, float pressure) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }
    public float getTemperature() {
        return temperature;
    }
    public float getHumidity() {
        return humidity;
    }
    public float getPressure() {
        return pressure;
    }
}
import java.util.Observable;
import java.util.Observer;
public class CurrentConditionsDisplay implements Observer, DisplayElement {
    Observable observable;
    private float temperature;
    private float humidity;
    public CurrentConditionsDisplay(Observable observable) {
        this.observable = observable;
        observable.addObserver(this);
    }
    public void update(Observable obs, Object arg) {
        if (obs instanceof WeatherData) { //obs가 WeatherData 클래스인지 확인
        WeatherData weatherData = (WeatherData)obs;
        this.temperature = weatherData.getTemperature();
        this.humidity = weatherData.getHumidity();
        display();
        }
    }
    public void display() {
        System.out.println(“Current conditions: “ + temperature
        + “F degrees and “ + humidity + “% humidity”);
    }
}
728x90

'디자인패턴' 카테고리의 다른 글

The Adapter and Facade Patterns  (0) 2023.10.21
The Command Pattern  (1) 2023.10.21
The Singleton Pattern  (1) 2023.10.21
Decorator Pattern  (2) 2023.10.21
Strategy Pattern  (0) 2023.10.18