You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 12:12:24