设计模式——观察者模式


一、基本知识

1.定义

定义对象间的一种一对多(变化)的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。个人感觉这个跟发布订阅模式有点像。

2.要点

①观察者模式使得我们可以独立地改变目标与观察者,从而使二者之间的关系松耦合。
②观察者自己决定是否订阅通知,目标对象并不关注谁订阅了。
③观察者不要依赖通知顺序,目标对象也不知道通知顺序。
④常用在基于事件的ui框架中,也是 MVC 的组成部分。
⑤常用在分布式系统中、actor框架中;

二、结构图

在这里插入图片描述

三、实例演示

实例:
气象站发布气象资料给数据中心,数据中心经过处理,将气象信息更新到两个不同的显示终端(A和B)。

1.普通代码

//客户端A
class DisplayA {
public:
    void Show(float temperature);
};

//客户端B
class DisplayB {
public:
    void Show(float temperature);
};

//气象资料数据
class WeatherData {
};

//数据中心
class DataCenter {
public:
    float CalcTemperature() {
        WeatherData* data = GetWeatherData();//得到气象资料数据
        float temper/*省略了对数据进行分析得到天气情况*/;
        return temper;
    }
private:
    WeatherData* GetWeatherData(); // 不同的方式
};

int main() {
    DataCenter* center = new DataCenter;
    DisplayA* da = new DisplayA;
    DisplayB* db = new DisplayB;

    float temper = center->CalcTemperature();//从数据中心获取数据
    da->Show(temper);//客户端A获取数据
    db->Show(temper);//客户端B获取数据
    return 0;
}
// 终端变化(增加和删除)   数据中心 不应该受终端变化的影响

2.观察者模式代码

#include <vector>

class IDisplay {
public:
    virtual void Show(float temperature) = 0;
    virtual ~IDisplay() {}
};

class DisplayA : public IDisplay {
public:
    virtual void Show(float temperature) {};
};

class DisplayB : public IDisplay {
public:
    virtual void Show(float temperature) {};
};

//气象资料
class WeatherData {
};

//数据中心分析气象资料
class DataCenter {
public:
    void Attach(IDisplay* ob) {};//将客户端加入到订阅者中
    void Detach(IDisplay* ob) {};//将客户端从订阅者中移除

    //数据中心直接给订阅者发布消息
    void Notify() {
        float temper = CalcTemperature();//得到分析后的数据
        //下面是直接通过订阅者调用订阅者函数,将数据传递给客户端
        for (auto iter = obs.begin(); iter != obs.end(); iter++) {
            (*iter)->Show(temper);
        }
    }

private:
    virtual WeatherData* GetWeatherData() {};//获取气象资料数据

    //对气象资料数据进行分析得到数据
    virtual float CalcTemperature() {
        WeatherData* data = GetWeatherData();
        float temper/* 省略对资料数据进行分析获取*/;
        return temper;
    }
    std::vector<IDisplay*> obs;//存放的是订阅者
};

int main() {
    DataCenter* center = new DataCenter;
    IDisplay* da = new DisplayA();
    IDisplay* db = new DisplayB();
    center->Attach(da);
    center->Attach(db);
    center->Notify();

    //-----
    center->Detach(db);
    center->Notify();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孟小胖_H

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值