In GoF observer pattern, the subject
is
class Subject {
public:
virtual ~Subject();
virtual void Attach(Observer*);
virtual void Detach(Observer*);
virtual void Notify();
protected:
Subject();
private:
List<Observer*> *_observers;
};
and the concrete subject ClockTimer
is given as
class ClockTimer : public Subject {
public:
ClockTimer();
virtual int GetHour();
virtual int GetMinute();
virtual int GetSecond();
void Tick();
};
I understand Subject
is abstract therefore all methods are virtual
. But why are the methods of ClockTimer
virtual? It's not an abstract class after all.
As cppreference says :
Virtual functions are member functions whose behavior can be overridden in derived classes . As opposed to non-virtual functions, the overriding behavior is preserved even if there is no compile-time information about the actual type of the class. That is to say, if a derived class is handled using pointer or reference to the base class, a call to an overridden virtual function would invoke the behavior defined in the derived class. Such a function call is known as virtual function call or virtual call.
So GoF has used virtual functions to override behaviour in derived classes.
The only method that must be virtual in the Observer pattern is Observer::update
. In the following code, SubjectBase
can correctly be used as a base class for a concrete subject (eg ClockTimer
) since the constructor and destructor are protected. The "state" methods of the concrete subject (eg GetHour
) do not need to be virtual.
Since SubjectBase
is non-virtual, the final
specifier cannot be used. This allows derived classes to define different behavior for the fundamental methods (ie attach
, detach
, and notify
). Unless there are pressing performance considerations, it is preferable to implement Subject
as a polymorphic class. Lastly, I see no fundamental reason to define the constructor as protected when Subject
is a polymorphic class.
#include <list>
class Observer {
public:
virtual ~Observer() = default;
virtual void update() = 0;
};
class ConcreteObserver : public Observer {
public:
void update() override;
};
class SubjectBase {
public:
void attach(Observer* o);
void detach(Observer* o);
void notify();
protected:
SubjectBase() = default;
~SubjectBase() = default;
private:
std::list<Observer*> m_observers;
};
class Subject {
public:
Subject() = default;
virtual ~Subject() = default;
virtual void attach(Observer* o) final;
virtual void detach(Observer* o) final;
virtual void notify() final;
private:
std::list<Observer*> m_observers;
};
class ConcreteSubject : public Subject {
public:
struct State;
State getState();
void attach(Observer* o); // compile time error!
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.