Java/Design Pattern

[헤드퍼스트 디자인 패턴] 2. 옵저버 패턴

noahkim_ 2024. 12. 16. 17:44

에릭 프리먼 님의 "헤드퍼스트 디자인 패턴" 책을 정리한 포스팅 입니다

 

1. 옵저버 패턴

  • 한 객체의 상태 변화가 있을 때, 그 객체에 의존하는 다른 객체들에게 자동으로 알림을 보내고, 이를 갱신할 수 있게 해주는 패턴
  • 일대다 형식으로 객체간 관계 정의

 

구성 요소

역할(Role) 설명
Subject
- state: 상태를 보유하고 관리함
- notify: 상태 변경 시 옵저버들에게 알림
- 옵저버 등록/제거 기능 제공
Observer
- Subject의 상태에 의존함
- Subject의 상태 변경 시 알림을 받고 처리 (update 메서드 등 구현)

 

느슨한 결합

  • 서로 강하게 연결되어 있지 않지만, 상호작용 할 수 있는 관계
구분 설명
추상화
- Subject는 Observer 인터페이스에만 의존
- 구체 구현을 몰라도 동작 가능
유연성
- 새로운 Observer 추가가 쉬움
- 변경이 있어도 서로 코드에 영향 없음
재사용성
- Subject와 Observer는 각각 독립적으로 재사용 가능

 

사용

사용 분야 설명
이벤트 기반 프로그래밍
- 사용자 입력, 시스템 이벤트 등에 반응
- 버튼 클릭, 알림 등에서 자주 사용
발행-구독 모델 (Pub-Sub)
- 발행자(Subject)가 메시지를 보내면 구독자(Observer)가 이를 수신
- 메시지 큐, 알림 시스템 등에서 활용

 

2. 예제: 가상 모니터링 애플리케이션

WeatherData

  • 센서로부터 오는 데이터를 추적
  • 새로운 데이터가 들어올 때마다 measurementsChange()가 호출됨

예) WeatherData

더보기
public interface Subject {
    void registerObserver(Observer o);
    void removeObserver(Observer o);
    void notifyObservers();
}
public class WeatherDate implements Subject {
    private List<Observer> observers;
    private float temperatures;
    private float humidity;
    private float pressure;
    
    public WeatherDate() { this.observers = new ArrayList<>(); }
    
    public void registerObserver(Observer o) { observers.add(o); }
    public void removeObserver(Observer o) { observers.remove(o); }
    public void notifyObservers() { 
    	for (Observer observer : observers) {
        	observer.update(temperature, humidity, pressure); 
        }        	
    }

    public int measurementsChanged() { notifyObservers(); }
    
    public void setMeaturements(float temperature, float humidity, float pressure) {
    	this.temperature = temperature;
       	this.humidity = humidity;
        this.pressure = pressure;
        
        measurementsChanged();
    }
}

 

Sensor

예) Sensor

더보기
public interface Observer {
    void update(float temp, float humidity, float pressure);
}
public interface DisplayElement {
    void display();
}
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);
    }
    
    public void update(float temperature, float humidity, float pressure) {
    	this.temperature = temperature;
        this.humidity = humidity;
        
        display();
    }
    
    public void display() {
    	System.out.println("현재상태: 온도 " + temperature + "F, 습도 " + humidity + "%");
    }
}