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

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

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

相关推荐
孞㐑¥4 小时前
Linux之Socket 编程 UDP
linux·服务器·c++·经验分享·笔记·网络协议·udp
水木兰亭7 小时前
数据结构之——树及树的存储
数据结构·c++·学习·算法
CoderCodingNo8 小时前
【GESP】C++四级考试大纲知识点梳理, (7) 排序算法基本概念
开发语言·c++·排序算法
秋风&萧瑟10 小时前
【C++】C++中的友元函数和友元类
c++
梁诚斌10 小时前
使用OpenSSL接口读取pem编码格式文件中的证书
开发语言·c++
2301_8035545214 小时前
c++中的绑定器
开发语言·c++·算法
海棠蚀omo14 小时前
C++笔记-位图和布隆过滤器
开发语言·c++·笔记
消失的旧时光-194315 小时前
c++ 的标准库 --- std::
c++·jni
GiraKoo15 小时前
【GiraKoo】C++11的新特性
c++·后端
不午睡的探索者15 小时前
告别性能瓶颈!Python 量化工程师,进击 C++ 高性能量化交易的“必修课”!
c++·github