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

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

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

相关推荐
郭源潮12 小时前
《Muduo网络库:实现TcpServer类终章》
服务器·网络·c++·网络库
MMjeaty5 小时前
查找及其算法
c++·算法
yong15858553436 小时前
1. Linux C++ muduo 库学习——库的编译安装
linux·c++·学习
mit6.8247 小时前
回溯剪枝trick
c++
渡我白衣8 小时前
C++世界的混沌边界:undefined_behavior
java·开发语言·c++·人工智能·深度学习·语言模型
却道天凉_好个秋8 小时前
c++ 协程
c++
无敌最俊朗@10 小时前
视频时间基 (time_base) 详解:时间的“刻度单位”
c++
脏脏a10 小时前
【C++ 入门】:引用、内联函数与 C++11 新特性(auto、范围 for、nullptr)全解析
开发语言·c++
AA陈超10 小时前
虚幻引擎5 GAS开发俯视角RPG游戏 P06-28 构建属性菜单小部件控制器
c++·游戏·ue5·游戏引擎·虚幻
恒者走天下10 小时前
cpp / c++零基础就业学习一站式学习平台
开发语言·c++·学习