본문 바로가기
컴퓨터과학/디자인패턴

[디자인패턴] 옵저버 패턴 (Observer Pattern)

by 윤호 2021. 10. 13.

목적

객체간 1:N 의존 관계를 정의함

한 개 객체 상태가 변경될 때, 그 객체와 의존 관계에 있는 모든 객체들이 자동으로 알림을 받고 상태를 갱신

대표적으로 채팅방, 구독 서비스가 옵저버 패턴을 이용함

방주인, 발행자는 Subject (또는 Observerable, Publisher) - subject에게 정보를 push

참여자, 구독자는 Observer (또는 Subscriber)

패턴 요소

문제: 1:N 관계에서 정보 갱신 - 구독자가 계속 loop를 돌며 업데이트가 있는지 확인할 수 없음

해결: 사용자를 등록하고, 정보가 변동하는 경우 알려주고 값을 자동으로 갱신

결과: loose coupling (구독자가 모든 정보를 아는게 아님), 확장성 (observer를 쉽게 추가/제거 가능)

 

구성

  • subject(observerable)에서 배열로 obeserver들을 저장
    • observer에서 subject를 추가할 때, subject의 addObserver 함수를 호출하여 자기 자신을 전달함
  • 정보가 변경되어 이를 제공할 때는 notifyObservers() 메소드를 사용 (update)
    • for 문을 돌며 모든 observer들에게 정보 제공

옵저버 패턴을 이용한 날씨 정보 전달

// Subject 구현 코드
public class WeatherData implements Subject {
    private ArrayList observers;
	...
 
    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
    }
    @Override
    public void removeObserver(Observer o) {
    	int i = observers.indexOf(o);
    	if (i >= 0) {
            observers.remove(i);
        }
    }
    @Override
    public void notifyObservers() {
        for (int i = 0; i < observers.size(); i++) {
            Observer observer = (Observer) observers.get(i);
            observer.update(temperature, humidity, pressure);
    	}
    }
 	...
 }

 

// Observer 구현 코드
public class CurrentConditionsDisplay implements Observer, DisplayElement {
    ...
    public CurrentConditionsDisplay(Subject weatherData) {
        this.weatherData = weatherData;
        weatherData.registerObserver(this); 
    }
    
    @Override
    public void update(float temperature, float humidity, float pressure) {
        this.temperature = temperature; 
        this.humidity = humidity; 
        display();
    }
    ...
}

 

// Main 함수
public static void main(String[] args) {
    WeatherData weatherData = new WeatherData();
    CurrentConditionsDisplay currentDisplay
    		= new CurrentConditionsDisplay(weatherData); 
    weatherData.setMeasurements(82, 70, 29.2f);
}

댓글