Я работаю над реализацией шаблона проектирования наблюдателя с объектом уведомления, который я могу изменить для соответствия различным наблюдаемым классам.
Вот структура наблюдателя:
notify.h:
class INotification //Notification container
{
public:
virtual ~INotification()=0;
};
inline INotification::~INotification() {}
class IObserver
{
public:
virtual ~IObserver();
virtual void update(INotification*)=0;
};
inline IObserver::~IObserver() {}
class ISubject
{
public:
virtual ~ISubject();
virtual void attach(IObserver*)=0;
virtual void detach(IObserver*)=0;
virtual void notify()=0; //Note: observer deletes notifications
};
inline ISubject::~ISubject() {}
Я реализую класс таймера, который я хочу, чтобы другие классы наблюдали за событиями таймера:
timer.h:
class ITimerObserver;
class ITimer : public ISubject
{
public:
virtual ~ITimer();
virtual void setInterval(const unsigned int,const unsigned int)=0; //Seconds, Microseconds
virtual void run()=0; //Check for triggering
virtual const timeval& now()=0;
virtual bool isItTime(const timeval&,const timeval&)=0;
};
inline ITimer::~ITimer() {}
class CTimer : public ITimer
{
protected:
std::vector<IObserver*> observers;
timeval interval; //How often we are triggering
timeval lastTrigger; //When we were last triggered
timeval current; //Our current time
private:
virtual ~CTimer();
virtual void attach(IObserver*);
virtual void detach(IObserver*);
virtual void notify();
virtual void setInterval(const unsigned int,const unsigned int); //Seconds, Microseconds
virtual void run(); //Check for triggering
virtual const timeval& now();
virtual bool isItTime(const timeval&,const timeval&);
};
class ITimerNotification : public INotification
{
public:
virtual ~ITimerNotification();
virtual const timeval& getTime()=0;
};
inline ITimerNotification::~ITimerNotification() {}
class CTimerNotification : public ITimerNotification
{
public:
CTimerNotification(const timeval& t)
{
time = t;
}
protected:
timeval time;
private:
virtual ~CTimerNotification();
virtual const timeval& getTime()
{
return time;
}
};
class ITimerObserver : public IObserver
{
public:
virtual void update(ITimerNotification*)=0;
};
Поэтому я хочу иметь возможностьдля передачи более конкретного объекта уведомления (A TimerNotification) всякий раз, когда происходит событие таймера, чтобы я мог вызвать определенную функцию update () для наблюдателя, поэтому я создал новый класс Observer (ITimerObserver).
Здесьэто функция, которая уведомляет наблюдателя о событии таймера:
void CTimer::notify()
{
std::vector<IObserver*>::iterator it;
for(it=observers.begin();it!=observers.end();++it)
{
ITimerNotification* notification = new CTimerNotification(now());
(*it)->update(notification);
}
}
Вот сам фактический наблюдатель:
class TestObserver : public ITimerObserver
{
public:
virtual void update(INotification* note)
{
std::cout<<"???: TestObserver: update()!\n";
}
virtual void update(ITimerNotification* note)
{
std::cout<< note->getTime().tv_sec << "." << note->getTime().tv_usec <<": TestObserver: update()!\n";
}
};
При запуске программа запускает метод интерфейса, void update (INotification) вместо более конкретного ITimerNotification, как я ожидал.Проблема в том, как мне узнать класс CTimer о TimerObserver, не нарушая контракт интерфейса, который говорит, что он принимает только указатель Base Observer?