블로그 이미지
자신의 단점을 메꾸는 것을 단(鍛)이라 하고 자신의 강점을 갈고 닦는 것을 련(鍊)이라 하여, 두가지를 합친 것을 단련이라고 부른다. 붕대마음

카테고리

전체목록 (664)
참고사이트 (8)
Goal (4)
Travel (10)
My Life (103)
Game (35)
Game Review (7)
Game Plan (0)
Books (5)
English (1)
Optimizing (12)
Study (217)
유용한 것들_etc (44)
유용한 것들_func (20)
Unity (48)
Unreal (87)
작업장 (54)
RenderMonkey (6)
정리요망 (1)
따라잡기 시리즈 (0)
링크용 (0)
Total339,492
Today19
Yesterday52
기상 정보 스테이션 시스템 구축.

필요한 것들.
1. 기상 스테이션(실제 기상 정보를 수집하는 장비)
2. WeatherData(기상 스테이션으로부터 오는 데이터를 추적)
3. 디스플레이(현재 기상조건을 보여줌)

class WeatherData 
{
float getTemperature(){}
float getHumidity(){}
float getPressure(){}
void measurementsChanged()
{
기상 관측값이 갱신될 때마다 알려줘야 한다.
}
};

ToDo!
세 함수 get~()는 단순히 Display에서 출력하기 위한 용도로 제공된다.
하지만 measurementsChanged()함수는 새로운 기상 측정 데이터가 나올 때 마다
호출되어서 정보를 갱신
해 줘야 한다.
Display에서도 새 정보가 있을 때 마다 갱신되어야 한다. 


void measurementsChanged()
{
      temperature = getTemperature();
      humidity = getHumidity();
      pressure = getPressure();

      display1.update(temperature, humidity, pressure); 
      display2.update(temperature, humidity, pressure);
      display3.update(temperature, humidity, pressure); 
} 
 
위 함수를 보면 이전에 말했던 내용을 충족해 주고 있다.
1. 새로운 기상 측정 데이터가 나올 때 마다 호출되어서 정보를 갱신.
2. Display에서도 새 정보가 있을 때 마다 갱신.

ToDo!
그런데 자세히 보면. display들의 update함수는 공통된 인터페이스를 사용하고 있다.
이 부분은 바뀔 수 있는 부분이기에 캡슐화를 해 줘야 한다.
그리고 display 자체도 하드코딩 되어 있다.
즉, 구체적인 구현에 맞춰서 코딩되었기 때문에 프로그램을 고치지 않고서는
기존 display를 빼거나 새 display를 추가할 수 없다.
이 부분도 수정되어야 한다.


이제 옵저버 패턴을적용 해 보자.
옵저버패턴에서는 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테
연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다 의존성을 정의.


올~ 좀 있어보임.
대략적인 내용은 한객체에 다른객체를 물려놓고 한 객체의 내용이 바뀌면 
바꼇다고 다른 객체들한테도 알림서비스 해주자!! 인듯.

// can register or remove in observer list by this interface
class Subject
{
public:
virtual void registerObserver(Observer* o)=0;
virtual void removeObserver(Observer* o)=0;
virtual void notifyObservers()=0;
};
옵저버로 등록,탈퇴,다른옵저버에게 알림을 위한 인터페이스. 

// if want to be observer, hav to implement this interface.
// this class only has a function of update.
class Observer
{
public:
virtual void update(float temp, float humidity, float pressure)=0;
};
옵저버가 되기위한 객체들을 위한 인터페이스.

서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는 
디자인을 사용해야 한다.
변경 사항이 생겨도 무난히 처리할 수 있다.
즉, 객체 사이의 상호 의존성을 최소화할 수 있다. 

class WeatherData : public Subject
{
        virtual void registerObserver(Observer* o)
{
Observers.push_back(o);
}
virtual void removeObserver(Observer* o)
        {
                vector<Observer*>::iterator it;
for(it = Observers.begin(); it!=Observers.end();)
{
if(*it == o)
                       { 
Observers.erase(it++);
                                return;
                        } 
else
it++;
} 
          } 
        virtual void notifyObservers()
{
vector<Observer*>::iterator it;
for(it = Observers.begin(); it!=Observers.end();)
{
(*it)->update(temperature, humidity, pressure);
it++;
}
} 


class  Display1 : public Observer
{
        virtual void update(float tempParam, float humidityParam, float pressureParam)
{
              정보 업데이트
        } 


이제 원했던 부분 수정이 모두 완료되었다.
Subject인터페이스를 통해 옵저버로 등록, 탈퇴를 할 수 있고
Observer을 통해 알림을 받을 수 있다. 
WeatherData를 보면 이 WeatherData의 정보값을 구독하고 싶으면 옵저버로 등록하면 되고
세부 내용이 업데이트되면 notifyObservers()를 통해 옵저버로 등록된 모든 객체에게
알림이 전송된다.

테스트 해 보자!!

1. WeatherData를 생성한다.
WeatherData* weather = new WeatherData;

2. Observer로 등록한다.
CurrentConditionsDisplay* currentDisplay = new CurrentConditionsDisplay(weather);
StatisticsDisplay* statistics = new StatisticsDisplay(weather);
ForecastDisplay* forecast = new ForecastDisplay(weather);

3. weather의 데이터가 변한다.
weather->setMeasurements(80,65,30.4f); 

4. Observer 탈퇴 후 데이터 변화.
weather->removeObserver(currentDisplay);
weather->setMeasurements(82,70,29.2f);
 

삭제된 currentObserver을 제외한 나머지 Observer 객체들의 정보가 갱신되었다.

 

'Books > Head First Design Patterns' 카테고리의 다른 글

Observer  (0) 2014.01.18
Posted by 붕대마음

최근에 달린 댓글

최근에 받은 트랙백

글 보관함