옵저버 패턴(Observer Pattern) (3/3) - Observer 패턴 변경 확장
[JAVA/Design Patterns] - 옵저버 패턴(Observer Pattern)(1/3) - java.util.Observable
[JAVA/Design Patterns] - 옵저버 패턴(Observer Pattern) (2/3) - Observer 패턴 직접 구현
4. Observer 패턴의 변경 및 확장
앞에서 JAVA 내장 API java.util.Observable 을 사용한 옵저버 패턴 구현과, 직접 인터페이스를 사용한 구현 두가지를 확인했다. 이제 이번 포스팅에서는 구현한 옵저버 패턴의 변경 및 확장을 어떻게 하면 되는지 알아본다.
아마 앞의 두 포스트를 잘 이해한 사람들은 어떻게 해야 될지 쉽게 머리속에 떠오를 것이다.
인터페이스를 구현한 옵저버패턴 UML이다.
다시 이야기하면, 기상스테이션(WeatherStation)에서 주기적으로 측정한 온도, 습도, 기압 정보를 WeatherData에 전달한다. WeatherData는 새로운 데이터를 받으면 Observer로 등록되어 있는 CurrentConditionDisplay와 ForecastDisplay에 새로운 데이터를 전달한다.
CurrentConditionDisplay와 ForecastDisplay는 새로 전달받은 데이터를 화면에 출력한다.
새로운 Observer 추가
여기서 새로운 Display 장비를 확장해보겠다.
어렵지 않다. Observer 와 DisplayElement를 implements 해서, update() 와 display() 메소드를 구현하고, 생성자에서 Observable에 Observer로 등록하면 된다.
이게 끝이다. 새로운 옵저버가 등록되었기에, 이후에 WeatherData는 새로운 옵저버에게도 데이터를 보낸다.
StaticsDisplay.java 를 추가해보자.
StaticsDisplay.java
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | public class StaticsDisplay implements Observer, DisplayElement{ // Observer, DisplayElement implements Observable observable; // 등록될 Observable private float maxTemp = 0.0f; // 최대 혼도 private float minTemp = 200; // 최저 온도 private float tempSum= 0.0f; // 온도 합 private int numReadings; // 데이터 수신 횟수 public StaticsDisplay(Observable observable) { // 생성자 this.observable = observable; // 등록될 Observable을 import observable.addObserver(this); // this(CurrentConditionPlay) 옵저버로 등록 } // update 로 새로운 데이터 갱신 public void update(Observable obs, Object arg) { if(obs instanceof WeatherData){ // Observable이 WeatherData인지 확인 WeatherData weatherData = (WeatherData)obs; float temp = weatherData.getTemperature(); this.tempSum += temp; // 온도 합 추가 numReadings++; // 데이터 수신 횟수 증가 if (temp > maxTemp) { // 최대 혼도 기록 maxTemp = temp; } if (temp < minTemp) { // 최저 온도 기록 minTemp = temp; } display(); // 화면 출력 } } // 화면 출력 public void display() { System.out.println("평균 온도 : "+ (tempSum / numReadings) +" , 최대 온도 : "+ maxTemp + ", 최저 온도 : " + minTemp); } } |
새로운 Display 장비인 StaticsDisplay.java 를 추가했다.
이게 전부이다. 이제 기상스테이션에서 WeatherData에 데이터를 던져주면, StaticsDisplay도 데이터를 받게 된다.
WeatherStation을 실행해보자. ( 생성자에서 StaticsDisplay 객체 생성도 해줘야 한다. )
WeatherStation.java
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | public class WeatherStation { static WeatherData weatherData; // weatherData Import static CurrentConditionDisplay currentDisplay; //currentConditionDisplay static ForecastDisplay forecastDisplay; // forecastDisplay static StaticsDisplay staticsDisplay; // staticsDisplay public static void weatherStation(){ // weatherStation 초기화 weatherData = new WeatherData(); // WeatherData 객체 생성 currentDisplay = new CurrentConditionDisplay(weatherData); // CurrentConditionDisplay 생성 (WeatherData에 옵저버 등록) forecastDisplay = new ForecastDisplay(weatherData); // ForecastDisplay 생성 (WeatherData에 옵저버 등록) staticsDisplay = new StaticsDisplay(weatherData); // StaticsDisplay 생성(WeatherData에 옵저버 등록) } // WeatherData의 setMeasurements 함수 실행 public static void changeWeather(float temp, float humity, float pressure) { weatherData.setMeasurements(temp, humity, pressure); } public static void main(String[] args){ weatherStation(); // WeatherStation 생성 // WeatherStation에서 날씨의 변화를 입력한다. System.out.println("-----날씨가 변한다.----"); changeWeather(40, 50, 10); // WeatherData에 새로운 데이터 전송 System.out.println(""); System.out.println("-----날씨가 변한다.----"); changeWeather(50, 60, 20); // WeatherData에 새로운 데이터 전송 System.out.println(""); } } |
WeatherStation을 실행하여 WeatherData에 데이터를 전송할때, StaticsDisplay도 데이터를 받아 값을 출력한다.
Observable을 implements 한 WeatherData는 기상스테이션으로 부터 전달받은 데이터를 옵저버에게 전달해준다.
온도, 습도, 기압 외에 추가적인 데이터를 전달하려면, WeatherData에 변수를 추가하고, 그 변수를 사용할 Display 장비에서 활용하면 된다.
WeatherData가 아닌 다른 종류의 Observable을 만들고 싶으면 Observable 인터페이스를 구현하면 된다.
그리고 디스플레이 장비에서는 해당 클래스에 addObserver() 를 사용해 옵저버로 등록해주면, 이 새로운 Observable 클래스로 부터 데이터를 전달 받을 수 있다.
옵저버 구조를 잘 이해하고 있다면, 변경 및 확장이 어렵지 않을 것이다.
소스 코드를 첨부했으니, 필요하면 다운받아서 확인하면 될 것이다.
소스코드 첨부
출처: https://hyeonstorage.tistory.com/167?category=549763 [개발이 하고 싶어요]
'JAVA > Design Patterns' 카테고리의 다른 글
[DesignPattern] 프록시 패턴 (0) | 2020.07.06 |
---|---|
[DesignPattern] 싱글턴 패턴 (0) | 2020.07.06 |
[DesignPattern] 디자인 패턴의 분류 (0) | 2020.07.06 |
[DesignPattern] 객체지향 모델링 (0) | 2020.07.06 |
옵저버 패턴(Observer Pattern) (2/3) - Observer 패턴 직접 구현 (0) | 2019.07.30 |
옵저버 패턴(Observer Pattern)(1/3) - java.util.Observable (0) | 2019.07.30 |
스트래티지 패턴 (strategy pattern) (0) | 2019.07.30 |
디자인 패턴의 분류 - Design Patterns (0) | 2019.07.30 |