Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- network configuration
- 스프링부트핵심가이드
- 자료구조와 함께 배우는 알고리즘 입문
- 데비안
- 서버설정
- 네트워크 설정
- 선형대수
- 스프링 시큐리티
- 페이징
- d
- 알파회계
- 코드로배우는스프링웹프로젝트
- iterator
- resttemplate
- 이터레이터
- 처음 만나는 AI수학 with Python
- 자바편
- 자료구조와함께배우는알고리즘입문
- 티스토리 쿠키 삭제
- baeldung
- 리눅스
- 코드로배우는스프링부트웹프로젝트
- 구멍가게코딩단
- GIT
- 친절한SQL튜닝
- 처음 만나는 AI 수학 with Python
- 목록처리
- ㅒ
- Kernighan의 C언어 프로그래밍
- /etc/network/interfaces
Archives
- Today
- Total
bright jazz music
Observer Pattern 1. 옵저버 패턴 본문
옵저버 패턴
- 옵저버 패턴은 객체들 사이에 일대다 관계를 정의한다. (Subject --> observers)
- 주제는 동일한 인터페이스를 써서 옵저버에게 연락한다.
- Observer 인터페이스를 구현하기만 하면 어떤 구상클래스의 옵저버라도 패턴에 참여할 수 있다.
- 주제는 옵저버들이 Observer인터페이스를 구현한다는 것을 제외하면 옵저버에 관해 전혀 모른다. 따라서 이들 사이의 결합은 느슨한 결합(loose coupling)이다.
- 옵저버 패턴을 사용하면 주제가 데이터를 보내거나(푸시 방식) 옵저버가 데이터를 가져올(풀 방식) 수 있다. 일반적으로 풀 방식이 더 옳은 방식이라고 간주한다.
- 스윙은 다른 여러 GUI프레임워크처럼 옵저버 패턴을 많이 사용한다.
- RxJava, 자바빈, RMI 외에 코코아나 스위프트, 자바스크립트와 같은 다른 언어의 프레임워크에서도 옵저버 패턴을 많이 사용한다.
- 옵저버 패턴은 여러 개의 주제와 메시지 유형이 있는 복잡한 상황에서 사용하는 출판-구독 패턴과 친척이다.
- 옵저버 패턴은 MVC 패턴과 깊은 연관이 있다.
//Subject.java
package com.example.designpatternstudy.observerPattern;
public interface Subject {
public void registerObserver(ObserverForObserverPattern observer);
public void removeObserver(ObserverForObserverPattern observer);
//주제의 상태가 변경되었을 때 모든 옵저버에게 변경내용을 알리기 위해 호출되는 메소드
public void notifyObservers();
}
//Subject 인터페이스 구현하기
package com.example.designpatternstudy.observerPattern;
import java.util.ArrayList;
import java.util.List;
public class WeatherData implements Subject{ //Subject인터페이스 구현
private List<ObserverForObserverPattern> observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observers = new ArrayList<ObserverForObserverPattern>();
}
@Override
public void registerObserver(ObserverForObserverPattern observer) {
observers.add(observer);
}
@Override
public void removeObserver(ObserverForObserverPattern observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
//모든 옵저버에게 상태 변화를 알려주는 부분
//모두 ObserverForObserverPattern인터페이스를 구현하는 객체들이므로
//update()메소드를 통해 손쉽게 상태 변화를 알려줄 수 있다.
for (ObserverForObserverPattern observer : observers) {
observer.update(temperature, humidity, pressure);
}
}
public void measuirementsChanged(){
notifyObservers();
}
public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measuirementsChanged();
}
}
//CurrentConditionDisplay.java
package com.example.designpatternstudy.observerPattern;
//weatherData객체로부터 변경사항을 받으려면 ObserverForObserverPattern을 구현해야 한다.
// API구조상 모든 디스플레이 항목에서 DisplayElement를 구현하기로 했기에 DisplayElement도 구현한다.
public class CurrentConditionDisplay implements ObserverForObserverPattern, DisplayElement{
private float temperature;
private float humidity;
private WeatherData weatherData;
//생성자에 weatherData라는 주제(Subject)가 전달되며, 그 객체를 써서 디스플레이를 옵저버로 등록한다.
public CurrentConditionDisplay(WeatherData weatherData){
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
@Override //ObserverForObserverPattern으로부터
public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
display();
}
@Override //DisplayElement로부터
public void display() { // 가장 최근에 받은 온도와 습도 출력
System.out.println("현재 상태: 온도 "
+ temperature + "F, 습도 " + humidity + "%");
}
}
package com.example.designpatternstudy.observerPattern;
public class StatisticsDisplay implements ObserverForObserverPattern, DisplayElement {
private float maxTemp = 0.0f;
private float minTemp = 200;
private float tempSum= 0.0f;
private int numReadings;
private WeatherData weatherData;
public StatisticsDisplay(WeatherData weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
public void update(float temp, float humidity, float pressure) {
tempSum += temp;
numReadings++;
if (temp > maxTemp) {
maxTemp = temp;
}
if (temp < minTemp) {
minTemp = temp;
}
display();
}
public void display() {
System.out.println("Avg/Max/Min temperature = " + (tempSum / numReadings)
+ "/" + maxTemp + "/" + minTemp);
}
}
package com.example.designpatternstudy.observerPattern;
public class ForecastDisplay implements ObserverForObserverPattern, DisplayElement {
private float currentPressure = 29.92f;
private float lastPressure;
private WeatherData weatherData;
public ForecastDisplay(WeatherData weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
}
public void update(float temp, float humidity, float pressure) {
lastPressure = currentPressure;
currentPressure = pressure;
display();
}
public void display() {
System.out.print("Forecast: ");
if (currentPressure > lastPressure) {
System.out.println("Improving weather on the way!");
} else if (currentPressure == lastPressure) {
System.out.println("More of the same");
} else if (currentPressure < lastPressure) {
System.out.println("Watch out for cooler, rainy weather");
}
}
}
package com.example.designpatternstudy.observerPattern;
public class WeatherStation {
public static void main(String[] args) {
//weatherData 객체 생성
WeatherData weatherData = new WeatherData();
CurrentConditionDisplay currentDisplay = new CurrentConditionDisplay(weatherData);
StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
//3개의 디스플레이를 생성하고 weatherData 객체를 인자로 전달
ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
weatherData.setMeasurements(80, 65, 30.4f);
//아래의 setMeasurements를 새로운 측정값으로 가정한다.
weatherData.setMeasurements(82, 70, 29.2f);
weatherData.setMeasurements(78, 90, 29.2f);
}
}
/*
> Task :WeatherStation.main()
현재 상태: 온도 80.0F, 습도 65.0%
Avg/Max/Min temperature = 80.0/80.0/80.0
Forecast: Improving weather on the way!
현재 상태: 온도 82.0F, 습도 70.0%
Avg/Max/Min temperature = 81.0/82.0/80.0
Forecast: Watch out for cooler, rainy weather
현재 상태: 온도 78.0F, 습도 90.0%
Avg/Max/Min temperature = 80.0/82.0/78.0
Forecast: More of the same
*/
Comments