GoF观察者模式:为何具体主题ClockTimer的方法需设为virtual?
关于GoF观察者模式中ClockTimer方法设为virtual的疑问解答
先看给出的类定义:
Subject抽象类
class Subject { public: virtual ~Subject(); virtual void Attach(Observer*); virtual void Detach(Observer*); virtual void Notify(); protected: Subject(); private: List<Observer*> *_observers; };
ClockTimer具体主题类
class ClockTimer : public Subject { public: ClockTimer(); virtual int GetHour(); virtual int GetMinute(); virtual int GetSecond(); void Tick(); };
为什么ClockTimer的GetHour等方法要设为virtual?
- 为后续子类扩展留有余地:ClockTimer现在是具体类,但难保以后不会派生子类,比如带时区的
TimeZoneClockTimer或者带夏令时的DaylightSavingClockTimer。如果这些状态方法不声明为virtual,子类重写后,通过ClockTimer*或ClockTimer&调用时,只会执行父类ClockTimer的实现,直接废掉多态特性。 - 适配观察者的调用逻辑:观察者(Observer)在收到
Notify()通知后,通常是通过Subject*指针来获取主题的状态(因为观察者持有的是抽象基类Subject的引用/指针)。如果ClockTimer的这些方法不是virtual,哪怕实际指向的是ClockTimer的子类,调用GetHour()也只能拿到ClockTimer的小时值,而不是子类的正确实现,会导致观察者获取的状态错误。 - 统一主题接口规范:把这些状态访问方法声明为virtual,相当于在Subject的子类层面定义了一套统一的状态获取接口,所有主题子类都遵循这个规范。观察者只需要依赖这套抽象接口,不用关心具体是哪个主题类,完全符合依赖倒置原则,让代码更灵活、易维护。
内容的提问来源于stack exchange,提问作者TMOTTM
相关产品推荐
相关产品推荐

