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

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

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

相关推荐
A懿轩A1 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
机器视觉知识推荐、就业指导1 小时前
C++设计模式:享元模式 (附文字处理系统中的字符对象案例)
c++
半盏茶香1 小时前
在21世纪的我用C语言探寻世界本质 ——编译和链接(编译环境和运行环境)
c语言·开发语言·c++·算法
Ronin3052 小时前
11.vector的介绍及模拟实现
开发语言·c++
✿ ༺ ོIT技术༻2 小时前
C++11:新特性&右值引用&移动语义
linux·数据结构·c++
字节高级特工2 小时前
【C++】深入剖析默认成员函数3:拷贝构造函数
c语言·c++
唐诺8 小时前
几种广泛使用的 C++ 编译器
c++·编译器
冷眼看人间恩怨9 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
红龙创客9 小时前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
Lenyiin9 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin