c++ 设计方式之 观察者模式

c++ 设计模式之 观察者模式

概念

观察者模式的目的是在对象之间的定义一对多的依赖关系当一个对象改状态时,所有依赖关系的对象全部收到通知并自动更新.

类图

c++ 设计方式之 观察者模式

示例代码

#include <iostream>
#include <vector>
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <string.h>
 
using namespace std ;
 
class Subject;
 
class Observer
{
public:
         Observer(){};
         ~Observer(){};
         virtualvoid Update(Subject* theChangeSubject) = 0;
};
 
class Subject
{
public:
         Subject(){};
         virtual~Subject() {};
         virtualvoid Attach(Observer*);
         virtualvoid Detach(Observer*);
         virtualvoid Notify(); 
private:
         vector<Observer*>_observers;
};
 
void Subject::Attach (Observer* o)
{
         _observers.push_back(o);
}
 
void Subject::Detach (Observer* o)
{
         intcount = _observers.size();
         inti;
 
         for(i = 0; i < count; i++) {
                   if(_observers[i]== o)
                            break;
         }
         if(i< count)
                   _observers.erase(_observers.begin()+ i);
 
}
 
void Subject::Notify ()
{
         intcount = _observers.size();
 
         for(int i = 0; i < count; i++)
                   (_observers[i])->Update(this);
}
 
class ClockTimer : public Subject
{
public:
         ClockTimer(){ _strtime( tmpbuf ); };
         intGetHour();
         intGetMinute();
         intGetSecond();
         voidTick();  
private:
         chartmpbuf[128];
};
 
/* Set time zone from TZ environmentvariable. If TZ is not set,
* the operating system is queried to obtainthe default value
* for the variable.
*/
void ClockTimer::Tick()
{
         _tzset();
 
         //Obtain operating system-style time.
         _strtime(tmpbuf );
         Notify();
}
 
int ClockTimer::GetHour()
{
         chartimebuf[128];
         strncpy(timebuf,tmpbuf, 2);
         timebuf[2]= NULL;
 
         returnatoi(timebuf);
}
 
int ClockTimer::GetMinute()
{
         chartimebuf[128];
         strncpy(timebuf,tmpbuf+3, 2);
         timebuf[2]= NULL;
 
         returnatoi(timebuf);
}
 
int ClockTimer::GetSecond()
{
         chartimebuf[128];
         strncpy(timebuf,tmpbuf+6, 2);
         timebuf[2]= NULL;
 
         returnatoi(timebuf);
}
 
 
class DigitalClock: public Observer
{
public:
         DigitalClock(ClockTimer*); 
         ~DigitalClock();  
         voidUpdate(Subject *);  
         voidDraw();    
private:
         ClockTimer*_subject; 
};
 
DigitalClock::DigitalClock (ClockTimer *s)
{
         _subject= s;
         _subject->Attach(this);
}
 
DigitalClock::~DigitalClock ()
{
         _subject->Detach(this);
}
 
void DigitalClock::Update (Subject*theChangedSubject)
{
         if(theChangedSubject== _subject)
                   Draw();
}
 
void DigitalClock::Draw ()
{
         inthour = _subject->GetHour();
         intminute = _subject->GetMinute();
         intsecond = _subject->GetSecond();
 
         cout<< "Digital time is " << hour << ":"
                   <<minute << ":"
                   <<second << endl;          
}
 
class AnalogClock: public Observer
{
public:
         AnalogClock(ClockTimer*); 
         ~AnalogClock();   
         voidUpdate(Subject *); 
         voidDraw();    
private:
         ClockTimer*_subject;  
};
 
AnalogClock::AnalogClock (ClockTimer *s)
{
         _subject= s;
         _subject->Attach(this);
}
 
AnalogClock::~AnalogClock ()
{
         _subject->Detach(this);
}
 
void AnalogClock::Update (Subject*theChangedSubject)
{
         if(theChangedSubject== _subject)
                   Draw();
}
 
void AnalogClock::Draw ()
{
         inthour = _subject->GetHour();
         intminute = _subject->GetMinute();
         intsecond = _subject->GetSecond();
 
         cout<< "Analog time is " << hour << ":"
                   <<minute << ":"
                   <<second << endl;
}
 
int main(void)
{
         ClockTimertimer;
 
         DigitalClockdigitalClock(&timer);
         AnalogClockanalogClock(&timer);
 
         timer.Tick(); 
 
         return0;
}