设计模式之观察者模式

设计模式之观察者模式,第1张

设计模式之观察者模式

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录
  • 一、定义
  • 二、要点
  • 三、结构图
  • 四、使用步骤
    • 1.一个不怎样的代码
    • 2.一个稍微较好的代码
  • 总结


一、定义

定义在对象间一种一对多的依赖关系,以便当一个对象的状态发生变化时,所有依赖它的对象都得到通知并自动更新。

二、要点
  1. 观察者模式使得我们可以独立的改变目标与观察者,从而使二者之间的关系松耦合。
  2. 观察者自己决定是否订阅通知,目标对象并不关注谁订阅了。
  3. 观察者不要依赖通知顺序,目标对象也不应该知道通知顺序。
  4. 常用在基于事件的ui框架中,也是mvc的组成部分。
  5. 常用于分布式系统中、actor框架。
  6. zookeeper、etcd、kafka、redis、分布式锁等等都会涉及到发布订阅模式。
三、结构图

四、使用步骤

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

1.一个不怎样的代码

代码如下(示例):

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

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

class WeatherData {
};

class DataCenter {
public:
    float CalcTemperature() {
        WeatherData * data = GetWeatherData();
        // ...
        float temper;
        return temper;
    }
private:
    WeatherData * GetWeatherData(); // 不同的方式获取 比如socket rpc 消息队列等等
};

int main() {
    DataCenter *center = new DataCenter;
    DisplayA *da = new DisplayA;
    DisplayB *db = new DisplayB;
    float temper = center->CalcTemperature();
    da->Show(temper);
    db->Show(temper);
    return 0;
}
2.一个稍微较好的代码

代码如下(示例):

#include 

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 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;
}

总结 1. 第一段代码如果一个显示终端要更新数据,它需要先去数据中心请求数据,数据中心需要去远程获取数据,获取到数据后再返回到显示终端,这样显示终端如果增加的更多,那么数据中心会显得异常繁忙。 2. 第二段代码通过数据中心定时去更新数据,然后主动的去下发到各个显示终端中。实现了观察者模式的设计模式方法。 3. 第二段代码还满足了面向接口,接口隔离的设计方法。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5683308.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存