/ DESIGN-PATTERNS

Observer Pattern(옵저버 패턴)

옵저버 패턴

  • 출판사(주체)와 구독자(옵저버) 의 느슨한 관계?..

시나리오

Head First 디자인패턴 참조 p.78~p.81 고객사로 부터 부탁받은

날씨측정하는 메소드

getTemparture()
getHumididy()

화면출력용 메소드 3개

currentConditionsDisplay(temp,humidity)
statisticsDisplay(temp,humidity)
forecastDisplay(temp,humidity)




1.날씨 측정하는 클레스

임시로 구현한 메소드들

public class WeatherData {


    public void measurementsChanged(){
        float temp = getTemperature();
        float humidity = getHumidity();

        //화면출력부분
        currentConditionsDisplay(temp,humidity);
        statisticsDisplay(temp,humidity);
        forecastDisplay(temp,humidity)
    }



    //임시구현
    private float getTemperature(){
        return (float) 17.1;
    }

    private float getHumidity(){
        return (float) 55.5;
    }

    private void currentConditionsDisplay(float temp, float humididy){
        System.out.println("온도:"+temp+"습도:"+humididy);
    }
    private void statisticsDisplay(float temp, float humididy){
        System.out.println("온도:"+temp+"습도:"+humididy);
    }
    private void forecastDisplay(float temp, float humididy){
        System.out.println("온도:"+temp+"습도:"+humididy);
    }

이런식으로 연결하면 화면이 추가될때마다 , 매번 코드를 수정해줘야함
(화면 출력부분 주석밑에)




2.더 좋은 방법이 없을까?

느슨한 관계로 묶어보자!

a.Subject 와 Observer 인터페이스 만들기!
interface Observer{
    public void update(float temp, float humidity);
}


public interface Subject {
    public void registerObserver(Observer observer);
    public void removeObserver(Observer observer);
    public void notifyObserver();
}

//자주 중복되는 Display부분도 인터페이스로 만들기
interface DisplayElement{
    public void display();
}




b.Subject 상속받기
public class WeatherData implements Subject{
    private List<Observer> observers;
    private float temp;
    private float humidity;

    public WeatherData() {
        observers = new ArrayList<>();
    }

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObserver() {
        for( Observer observer : observers){
            observer.update(temp,humidity);
        }
    }

    public void measurementsChanged(){
        notifyObserver();
    }

    public void setMeasurements(float temp, float humidity){
        this.temp = temp;
        this.humidity = humidity;
        measurementsChanged();
    }

}




b.Observer 상속받기(Display도)
class CurrentConditionsDisplay implements Observer, DisplayElement{
    private float temp;
    private float humidity;
    private Subject weatherData;

    //옵저버 등록하는 생성자
    public CurrentConditionsDisplay(Subject weatherData) {
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }

    @Override
    public void update(float temp, float humidity) {
        this.temp = temp;
        this.humidity = humidity;
        display();
    }

    @Override
    public void display() {
        System.out.printf("온도:"+this.temp);
        System.out.printf("습도:"+this.humidity);
        System.out.println();
    }
}

테스트

    public static void main(String[] args) {
        WeatherData2 wd = new WeatherData2();

        CurrentConditionsDisplay cd = new CurrentConditionsDisplay(wd);
        wd.setMeasurements((float) 30,(float) 44.5);
        wd.setMeasurements((float) 20,(float) 24.5);
        wd.setMeasurements((float) 10,(float) 64.5);
    }

콘솔창

온도:30.0습도:44.5
온도:20.0습도:24.5
온도:10.0습도:64.5

디자인 패턴 목록