Observer
Books/Head First Design Patterns / 2014. 1. 18. 15:36
기상 정보 스테이션 시스템 구축.
필요한 것들.
1. 기상 스테이션(실제 기상 정보를 수집하는 장비)
2. WeatherData(기상 스테이션으로부터 오는 데이터를 추적)
3. 디스플레이(현재 기상조건을 보여줌)
1. 새로운 기상 측정 데이터가 나올 때 마다 호출되어서 정보를 갱신.
2. Display에서도 새 정보가 있을 때 마다 갱신.
ToDo!
그런데 자세히 보면. display들의 update함수는 공통된 인터페이스를 사용하고 있다.
이 부분은 바뀔 수 있는 부분이기에 캡슐화를 해 줘야 한다.
그리고 display 자체도 하드코딩 되어 있다.
즉, 구체적인 구현에 맞춰서 코딩되었기 때문에 프로그램을 고치지 않고서는
기존 display를 빼거나 새 display를 추가할 수 없다.
이 부분도 수정되어야 한다.
이제 옵저버 패턴을적용 해 보자.
옵저버패턴에서는 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테
연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다 의존성을 정의.
올~ 좀 있어보임.
대략적인 내용은 한객체에 다른객체를 물려놓고 한 객체의 내용이 바뀌면
바꼇다고 다른 객체들한테도 알림서비스 해주자!! 인듯.
서로 상호작용을 하는 객체 사이에서는 가능하면 느슨하게 결합하는
디자인을 사용해야 한다.
변경 사항이 생겨도 무난히 처리할 수 있다.
즉, 객체 사이의 상호 의존성을 최소화할 수 있다.
필요한 것들.
1. 기상 스테이션(실제 기상 정보를 수집하는 장비)
2. WeatherData(기상 스테이션으로부터 오는 데이터를 추적)
3. 디스플레이(현재 기상조건을 보여줌)
class WeatherData
{
float getTemperature(){}
float getHumidity(){}
float getPressure(){}
void measurementsChanged()
{
기상 관측값이 갱신될 때마다 알려줘야 한다.
}
};
ToDo!
세 함수 get~()는 단순히 Display에서 출력하기 위한 용도로 제공된다.
하지만 measurementsChanged()함수는 새로운 기상 측정 데이터가 나올 때 마다
호출되어서 정보를 갱신 해 줘야 한다.
Display에서도 새 정보가 있을 때 마다 갱신되어야 한다.
위 함수를 보면 이전에 말했던 내용을 충족해 주고 있다.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);
} 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
{
class Display1 : public Observer
{
이제 원했던 부분 수정이 모두 완료되었다.
Subject인터페이스를 통해 옵저버로 등록, 탈퇴를 할 수 있고
Observer을 통해 알림을 받을 수 있다.
WeatherData를 보면 이 WeatherData의 정보값을 구독하고 싶으면 옵저버로 등록하면 되고
세부 내용이 업데이트되면 notifyObservers()를 통해 옵저버로 등록된 모든 객체에게
알림이 전송된다.
테스트 해 보자!!
1. WeatherData를 생성한다.
WeatherData* weather = new WeatherData;
2. Observer로 등록한다.
4. Observer 탈퇴 후 데이터 변화.
삭제된 currentObserver을 제외한 나머지 Observer 객체들의 정보가 갱신되었다.
virtual void registerObserver(Observer* o)
{
Observers.push_back(o);
}
virtual void removeObserver(Observer* o)
}
}
{
vector<Observer*>::iterator it;
vector<Observer*>::iterator it;
for(it = Observers.begin(); it!=Observers.end();)
{
if(*it == o)
{
{
Observers.erase(it++);
return;
}
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);
3. weather의 데이터가 변한다.
weather->setMeasurements(80,65,30.4f);
4. Observer 탈퇴 후 데이터 변화.
weather->removeObserver(currentDisplay);
weather->setMeasurements(82,70,29.2f);
'Books > Head First Design Patterns' 카테고리의 다른 글
Observer (0) | 2014.01.18 |
---|
댓글을 달아 주세요