Observer Pattern - Simple
C++ 2008. 1. 21. 12:25 |
Observer Pattern을 공부중..
데이터와 뷰가 분리 되어 있을때 하나의 데이터를 두개 이상의 뷰에 의존적일 경우에
이 패턴을 사용하면 되는거 같아요.
즉, 데이터를 두개의 뷰에 업데이트가 가능하며, 하나의 뷰에서 데이터가 수정된 후에
다른 뷰에도 업데이트가 가능하게 됩니다.
// ObserverPattern.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <list>
using namespace std;
//////////////////////////////////////////////////////////////////////////
class Subject;
class Observer
{
public:
virtual ~Observer() {};
virtual void Update(Subject* theChangedSubject) = 0;
protected:
Observer() {};
};
//////////////////////////////////////////////////////////////////////////
class Subject
{
public:
virtual ~Subject() {};
virtual void Attach(Observer*);
virtual void Detach(Observer*);
virtual void Notify();
protected:
Subject() {};
private:
list<Observer*> _observers;
};
void Subject::Attach(Observer* o)
{
_observers.push_back(o);
}
void Subject::Detach(Observer* o)
{
_observers.remove(o);
}
void Subject::Notify()
{
list<Observer*>::iterator iter;
for(iter = _observers.begin(); iter != _observers.end(); ++iter)
{
(*iter)->Update(this);
}
}
//////////////////////////////////////////////////////////////////////////
class ClockTime : public Subject
{
public:
ClockTime() {}
virtual int GetHour() { return 0; }
virtual int GetMinute() { return 0; }
virtual int GetSecond() { return 0; }
void Tick();
};
void ClockTime::Tick()
{
Notify();
}
//////////////////////////////////////////////////////////////////////////
class Output
{
public:
Output() {}
virtual ~Output() {}
void Draw() {
printf("Output....\n");
}
};
//////////////////////////////////////////////////////////////////////////
class DigitalClock : public Output, public Observer
{
public:
DigitalClock(ClockTime*);
virtual ~DigitalClock();
virtual void Update (Subject*);
virtual void Draw();
private:
ClockTime* _subject;
};
DigitalClock::DigitalClock(ClockTime* s)
{
_subject = s;
_subject->Attach(this);
}
DigitalClock::~DigitalClock()
{
_subject->Detach(this);
}
void DigitalClock::Update(Subject* theChangedSubject)
{
if(theChangedSubject == _subject)
Draw();
}
void DigitalClock::Draw()
{
int hour = _subject->GetHour();
int minute = _subject->GetMinute();
Output::Draw();
}
//////////////////////////////////////////////////////////////////////////
class AnalogClock : public Output, public Observer
{
public:
AnalogClock(ClockTime*);
virtual ~AnalogClock();
virtual void Update(Subject*);
virtual void Draw();
void TestChange();
private:
ClockTime* _subject;
};
AnalogClock::AnalogClock(ClockTime* s)
{
_subject = s;
_subject->Attach(this);
}
AnalogClock::~AnalogClock()
{
_subject->Detach(this);
}
void AnalogClock::Update(Subject* theChangedSubject)
{
if(theChangedSubject == _subject)
Draw();
}
void AnalogClock::Draw()
{
int hour = _subject->GetHour();
int minute = _subject->GetMinute();
Output::Draw();
}
void AnalogClock::TestChange()
{
_subject->Notify();
}
/************************************************************************/
/* */
/************************************************************************/
int _tmain(int argc, _TCHAR* argv[])
{
ClockTime* timer = new ClockTime();
AnalogClock* analogClock = new AnalogClock(timer);
DigitalClock* digitalclock = new DigitalClock(timer);
timer->Tick();
analogClock->TestChange();
delete timer;
delete analogClock;
delete digitalclock;
return 0;
}