观察者(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

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

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

相关推荐
旖旎夜光1 小时前
【C++ 基础入门】C++多态(下):单/多继承虚表、多态补充与 21 道高频题
开发语言·c++·笔记·学习
apcipot_rain11 小时前
C++转Java日记(03)
java·开发语言·c++
布莱克60511 小时前
C++ 中 map 的 insert 与 emplace:key 已存在时会覆盖吗?
开发语言·数据结构·c++·算法·map
xys_67812 小时前
深挖C++:类和对象(中)
开发语言·c++
D e re k ZH14 小时前
C++ 系统学习手记:从语法细节到工程实践
开发语言·数据结构·c++·算法
xiaoye-duck15 小时前
《C++ 项目:手写大模型接入 SDK》Ollama接口设计(上):初始化、全量响应实现和测试
开发语言·网络·c++·语言模型
zaizai100716 小时前
【Effective Modern C++】学习第一章
c++
Fruiticecake16 小时前
C 程序员速通现代 C++(一):lambda、std::function、移动语义与智能指针
c语言·c++
青少儿编程课堂17 小时前
蓝桥杯·全国青少年信息素养大赛·电子学会Python/C++考级:中缀表达式求值解析
c++·python·算法·bfs·信息学竞赛
坤坤子吖19 小时前
Linux网络编程:TCP服务器的多进程与多线程实现
linux·服务器·开发语言·网络·c++·笔记·学习