观察者(observer)模式

一对多关系

松耦合

《Head First设计模式》p38

现在有三个使用天气数据的布告板。

布告板1,布告板2,布告板3

错误示范:

cpp 复制代码
#ifndef WEATHERDATA_H
#define WEATHERDATA_H


class WeatherData
{
public:
    WeatherData();
    /**
     * @brief getTemperature    得到温度
     * @return
     */
    double getTemperature()
    {
        return 1;
    }
    /**
     * @brief getHumidity   得到湿度
     * @return
     */
    double getHumidity()
    {
        return 1;
    }
    /**
     * @brief getPressure   得到气压
     * @return
     */
    double getPressure()
    {
        return 1;
    }
    /**
     * @brief measurementschanged   一旦气象测量更新,此方法会被调用
     */
    void measurementschanged()
    {
        //获取温度,湿度,气压
        //更新布告板1
        //更新布告板2
        //更新布告板3
    }
};

#endif // WEATHERDATA_H

针对具体实现编程,会导致我们以后在增加或删除布告板时必须修改该部分代码。


观察者模式

主题(subject)

观察者(observer)

主题对象管理某些数据

当主题内的数据改变,会通知观察者

观察者已经订阅主题以便在主题数据改变时能收到更新。

观察者模式定义了对象之间的一对多依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

cpp 复制代码
#ifndef SUBJECT_H
#define SUBJECT_H

#include "observer.h"
/**
 * @brief The Subject class 抽象的主题类
 */
class Subject
{
public:
    Subject();
    /**
     * @brief registerObserver  注册观察者
     */
    virtual void registerObserver(Observer * o)
    {

    }

    /**
     * @brief removeObserver    移除观察者
     */
    virtual void removeObserver(Observer * o)
    {

    }

    /**
     * @brief notifyObservers   通知观察者们
     */
    virtual void notifyObservers()
    {

    }
};


#endif // SUBJECT_H
cpp 复制代码
#ifndef OBSERVER_H
#define OBSERVER_H

/**
 * @brief The Observer class    抽象的观察者类
 */
class Observer
{
public:
    Observer();
    /**
     * @brief update    当主题状态改变时,update()被调用
     */
    void update();
};

#endif // OBSERVER_H

设计原则:

为了交互对象之间的松耦合设计而努力。

这样可以建立有弹性的OO系统,能够应对变化。

cpp 复制代码
#ifndef WEATHERDATA_H
#define WEATHERDATA_H

#include "subject.h"
#include <QHash>
class WeatherData : public Subject
{
public:
    WeatherData();
    /**
     * @brief getTemperature    得到温度
     * @return
     */
    double getTemperature()
    {
        return 1;
    }
    /**
     * @brief getHumidity   得到湿度
     * @return
     */
    double getHumidity()
    {
        return 1;
    }
    /**
     * @brief getPressure   得到气压
     * @return
     */
    double getPressure()
    {
        return 1;
    }
    /**
     * @brief measurementschanged   一旦气象测量更新,此方法会被调用
     */
    void measurementschanged()
    {
        //获取温度,湿度,气压
        //通知观察者
        notifyObservers();
    }

    virtual void registerObserver(Observer * o)
    {
        mObservers.insert(o);
    }

    virtual void removeObserver(Observer * o)
    {
        mObservers.removeOne(o)
    }

    virtual void notifyObservers()
    {
        foreach (auto var, mObservers) {
            var->update();
        }
    }
private:
    QList<Observer*> mObservers;
};

#endif // WEATHERDATA_H

采取观察者模式:主题的数据安全性有所保障。

可以从被观察者处推或拉数据。

相关推荐
王老师青少年编程8 小时前
csp信奥赛C++高频考点专项训练之字符串 --【子串查找】:[NOIP 2009 提高组] 潜伏者
c++·字符串·csp·高频考点·信奥赛·子串查找·潜伏者
初願致夕霞8 小时前
基于系统调用的Linux网络编程——UDP与TCP
linux·网络·c++·tcp/ip·udp
小小de风呀10 小时前
de风——【从零开始学C++】(五):内存管理
开发语言·c++
CHANG_THE_WORLD11 小时前
C语言中的 %*s 和 %.*s 和C++的字符串格式化输出
c语言·c++·c#
螺丝钉的扭矩一瞬间产生高能蛋白12 小时前
QT的C++接口基础用法
c++·qt·嵌入式软件·嵌入式linux·linux应用
智者知已应修善业13 小时前
【51单片机模拟生日蜡烛】2023-10-10
c++·经验分享·笔记·算法·51单片机
智者知已应修善业13 小时前
【51单片机如何让LED灯从一亮到八,再从八亮到一】2023-10-13
c++·经验分享·笔记·算法·51单片机
qeen8713 小时前
【数据结构】二叉树相关经典函数C语言实现
c语言·数据结构·c++·笔记·学习·算法·二叉树
良木生香13 小时前
【C++初阶】STL——List从入门到应用完全指南(1)
开发语言·数据结构·c++·程序人生·算法·蓝桥杯·学习方法