정의(Definition)
옵저버 패턴(Observer Pattern)이란,
동일한 데이터를 여러 곳에서 사용하는 경우
서로 다른 표현 양식간에 데이터의 일관성을 유지시켜주는 방법으로 사용한다.
예(Example)
성적 데이터를 여러가지 형식의 그래프로 표현하는 경우, 성적 데이터는 Subject이고, Observer는 그래프이다.
옵저버 패턴이 유용한 경우:
. 하나의 객체가 두 가지 이상의 모습을 가질 때 옵저버 패턴을 적용시키면 재사용성이 높아지고, 변경이 용이해진다.
. 한 객체에 대한 변경이 다른 객체들에게도 영향을 미치는 상황에서,
얼마나 많은 객체가 영향을 받는지 일일이 관리하고 싶지 않을 때 유용하다.
. 하나의 객체가 다른 객체에게 변경 사항을 알려주어야 하는데,
구체적으로 어떤 객체들에게 통보를 해야 할 지 알지 못할 때 유용하다.
습작:
옵저버 패턴을 모듈화 해 보았다.
데이터라는 것은 어느 프로그램에나 존재하므로, 유용하게 사용할 수 있을 것 같다.
|
#ifndef _DESIGN_PATTERN_OBSERVER_H_
#define _DESIGN_PATTERN_OBSERVER_H_
#include <vector>
#include <algorithm>
class Observer;
class Subject;
class Observer
{
public:
virtual void update(Subject *subject) = 0;
};
class Subject
{
public:
void addObserver(Observer *observer)
{
std::vector<Observer*>::iterator iter = std::find(m_observers.begin(), m_observers.end(), observer);
if(iter != m_observers.end()) {
return;
}
m_observers.push_back(observer);
}
void eraseObserver(Observer *observer)
{
std::vector<Observer*>::iterator iter = find(m_observers.begin(), m_observers.end(), observer);
if(iter != m_observers.end()) {
m_observers.erase(iter);
}
}
void notifyObserver()
{
for(std::vector<Observer*>::iterator iter = m_observers.begin() ; iter != m_observers.end() ; iter++) {
(*iter)->update(this);
}
}
private:
std::vector<Observer*> m_observers;
};
#endif
|
|
다음은 테스트케이스다.
main.cpp :
|
#include "Observer.h"
class News : public Subject
{
public:
int GetNumber() const { return number; }
void SetNumber(int val) { number = val; }
private:
int number;
};
class NewsPaper : public Observer
{
public:
NewsPaper() : number(0) {}
public://concretClassA
void display()
{
printf("number: %d \n", number);
}
public://Observer class
void update(Subject *subject)
{
News *news = (News*)subject;
this->number = news->GetNumber(); }
private:
int number;
};
int main()
{
News news;
NewsPaper *paper1 = new NewsPaper();
NewsPaper *paper2 = new NewsPaper();
NewsPaper *paper3 = new NewsPaper();
news.addObserver(paper1);
news.addObserver(paper2);
news.addObserver(paper3);
news.addObserver(paper3);
news.eraseObserver(paper3);
news.SetNumber(5);
news.notifyObserver();
paper1->display();
paper2->display();
paper3->display();
return 0;
}
|
|