개발/flutter

[Flutter] Dart 옵저버 패턴 Observer pattern

덤벨로퍼 2020. 9. 4. 17:57

옵저버 패턴

 

옵저버패턴은 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 옵저버는 업데이트가 된다.