Free Lines Arrow
본문 바로가기
Design pattern/GoF(HeadFirst)

[HeadFirst] 옵저버 패턴

by skahn1215 2022. 12. 3.
728x90
반응형

정의

  • 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체엑 연락이 간다.
  • 자동으로 내용이 갱신되는 방식이다.
  • 1 : N 구조를 가진다. 
  • 아래 처럼 주체 에서 B 로 값이 변경되는 경우 관련된 객체에게 알려줘야 한다.

 

구조

 

Subject

  • 주제를 나타내는 인터페이스 즉 여기서 값이 변경되면 등록된 옵저버들에게 알려준다.
  • 옵저버 등록 삭제를 여기서 한다.

ConcreateSubject

  • 주제 역할을 하는 구체 클래스이다.
  • 옵저버를 등록하기 위한 등록, 해제 메소드, notifyObservers()메소드로 구현한다.

Observer

  • 옵저버가 될수 있는 객체는 반드시 해당 인터페이를 구현해야 한다.
  • update 메소드 밖에 없다.

ConcreateObserver

  • Observer 인터페이스의 구체화 이다.
  • 무엇이든 옵저버 클래스가 될 수 있다.

 

코드

기본 인터페이스

public interface Observer {
    public void update(float temp, float humidity, float pressure);
}

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

public interface DisplayElement {
    public void display();
}

 

Subject 구체화 클래스

Subject(WeatherData)

주체 클래스이다, 여기서 옵저버들을 관리하고

데이터 변경시 알려주는 역할을 한다.

package headfirst.patterns.observer.wheather;

import lombok.Getter;

import java.util.ArrayList;
import java.util.List;

@Getter
public class WeatherData implements Subject {
    private List<Observer> observers;

    private float temperature;
    private float humidity;
    private float pressure;

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

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

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

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

    public void measurementsChanged() {
        notifyObserver();
    }

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

 

Observser1 (CurrentConditionsDisplay)

  • Observer 를 구현: 다형성으로 옵저버로 등록할수있다.
  • DisplayElement: 화면에 display 를 한다.
  • 코드를 보면 업데이트 하는 경우 무조건 화면에 데이터를 표시한다.
  • 주체 객체를 받아 자기 자신을 옵저버로 등록한다.
package headfirst.patterns.observer.wheather;

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);
    }

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


    @Override
    public void display() {
        System.out.println("현재 상태: 온도 "+temperature+" F, 습도 "+humidity+"%");
    }
}

 

Observser2 (StatisticsDisplay)

  • 코드 업데이트 된경우 값만 달리하여 원하는 값을 보여준다.
package headfirst.patterns.observer.wheather;

public class StatisticsDisplay implements Observer, DisplayElement{
    private float maxTemp = 0.0f;
    private float minTemp = 200;
    private float tempSum= 0.0f;
    private int numReadings;
    public WeatherData weatherData;

    public StatisticsDisplay(WeatherData weatherData) {
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }

    @Override
    public void update(float temp, float humidity, float pressure) {
        tempSum += temp;
        numReadings++;

        if (temp > maxTemp) {
            maxTemp = temp;
        }

        if (temp < minTemp) {
            minTemp = temp;
        }

        display();
    }

    @Override
    public void display() {
        System.out.println("Avg/Max/Min temperature = " + (tempSum / numReadings)
                + "/" + maxTemp + "/" + minTemp);
    }
}

 

 

전체 소스 코드

https://github.com/rnrl1215/design-pattern/tree/main/src/main/java/headfirst/patterns/observer/wheather

 

GitHub - rnrl1215/design-pattern

Contribute to rnrl1215/design-pattern development by creating an account on GitHub.

github.com

 

 

 

참고:https://search.shopping.naver.com/book/catalog/32473420628?cat_id=50010881&frm=PBOKMOD&query=%ED%97%A4%EB%93%9C%ED%8D%BC%EC%8A%A4%ED%8A%B8+%EB%94%94%EC%9E%90%EC%9D%B8+%ED%8C%A8%ED%84%B4&NaPm=ct%3Dlbak3mk8%7Cci%3D62392e56ce8bebbb0a2f80b4a5f7e3fc584acbce%7Ctr%3Dboknx%7Csn%3D95694%7Chk%3Dcf9b3bc3328b88dac17fc59b876b517fc2cc2c69

 

헤드 퍼스트 디자인 패턴 : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

 

728x90
반응형

'Design pattern > GoF(HeadFirst)' 카테고리의 다른 글

[HeadFirst] 커맨드 패턴  (0) 2023.02.10
[HeadFirst] 데코레이터 패턴  (0) 2023.01.07

댓글