[Flutter] Dart 옵저버 패턴 Observer pattern
옵저버 패턴
옵저버패턴은 Subject 와 Observer 로 구성된다.
다수의 Observer 들이 하나의 Subject 를 구독하고 Subject 에서 Observer 들에게 알림을줄수있는 구조이다.
유튜브 채널을 구독하면 구독자들이 채널의 영상을 볼수 있는것처럼 1:다수 의 구조이며
느슨한결합 으로 되어있다. (Subject는 Observer들을 몰라도 되고, observer 를 더 추가 해도되고 옵저버가 변해도 영향 받지않음)
구현
일기예보 정보를가진 Subject가 있고
그게 바뀌면 일기예보를 구독한 화면들이 바뀌는 것을 구현하려한다.
abstract class Subject{
registerObserver(Observer o);
removeObserver(Observer o);
notifyObserver();
}
class WeatherData implements Subject{
List<Observer> _observers = [];
double _temparature;
double _humidity;
double _pressure;
//옵저버 추가
registerObserver(Observer o){
print(o);
_observers.add(o);
print('registered');
}
//옵저버 삭제
removeObserver(Observer o){
_observers.remove(o);
}
//옵저버 알림!
notifyObserver(){
print('notify');
print(_observers.length);
_observers.map((observer){
print('test');
observer.update(_temparature,_humidity,_pressure);
}).toList();
}
measurementsChange(){
print('measurementsChange');
notifyObserver();
}
//측정값 변경
setMeasurements(double temp, double humid , double pressure){
print('setMeasurements');
this._temparature = temp;
this._humidity = humid;
this._pressure = pressure;
measurementsChange();
}
}
Subject 라는 인터페이스를 만들어주고
WhetherData 클래스에서 implement 해준다.
측정값이 변할때 이 Subject 에서는 변경 값을 가지고
Subject를 구독한 각 옵저버들의 update 함수를 실행시킨다.
abstract class Observer{
update(double temp, double humidity,double pressure);
}
abstract class DisplayElement{
display();
}
class CurrentConditionDisplay implements Observer, DisplayElement{
CurrentConditionDisplay({this.weatherData}){
weatherData.registerObserver(this); //구독
}
Subject weatherData;
double temp;
double humid;
update(double temp, double humidity,double pressure){
this.temp = temp;
this.humid = humidity;
display();
}
display(){
print('display $temp $humid');
}
}
CurrentConditionDisplay 라는 옵저버는 Observer , DisplayElement 두개의 인터페이스를 implement 한다.
이런식으로 행동에따라 인터페이스를 나누면 좋다. (더라..)
CurrentConditionDisplay 는 변수에 온도와 습도를 가지고있고
weatherData Subject 를 인자로 받아 생성과 동시에 Subject를 구독한다.
그리고 update 함수가 실행되고나서 변경값을 display 해준다.
//실행
var data = WeatherData();
//옵저버 생성과 동시에 subject 구동
var currentConditionDisplay = CurrentConditionDisplay(weatherData:data);
//subject 변경시 update
data.setMeasurements(50,20,14);
data.setMeasurements(26,28,19);
data.setMeasurements(94,95,47);
이렇게 날씨정보 Subject 에 새로운값을 set을 할때마다
자동으로 currentConditionDisplay 옵저버는 업데이트가 된다.