【C++设计模式】二十六、观察者模式

一、基本概念

基于map的观察者模式:定义对象之间的一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。又称为依赖,发布-订阅。

存在两个部分:

  1. 观察者观察事件是否发生,发生通知监听者(具体观察者)。
  2. 监听者 (具体观察者):处理事件。

如微信的消息提醒,订阅号提醒,就是观察者监听是否有消息到来,发生后,提醒监听者去处理。

【1. 优点:】

  • 观察者模式可以实现表示层和数据逻辑层的分离,定义了稳定的消息传递机制,并抽象了更新接口,使得可以有各种各样的表示层充当具体观察者角色。
  • 观察者模式在观察目标和观察者之间建立了一个抽象的耦合观察者对象只需维持一个抽象观察者的集合,无需了解其具体观察者。
  • 观察者模式支持广播通信,观察目标会像所有已注册的观察者发起通知,降低了一对多系统的设计难度。
  • 观察者模式满足开放-封闭原则,增加新的具体观察者无须修改原有的系统代码。

【2. 缺点:】

  • 如果一个观察目标对象有很多的直接观察者和间接观察者,那么所有的观察者接收消息会 耗费大量的时间。
  • 如果观察者和被观察者之间存在循环依赖,那么观察目标会出发它们之间进行循环调用,可能导致系统崩溃。

【3. 使用场景:】

  • 当一个抽象对象有两个方面,其中一方面依赖于另一方面,将这两者封装在独立的对象中,实现独立的改变,进行依赖。
  • 当一个对象的的数据变化时需要通知其他对象,不希望这些对象是紧密耦合的,即不知道具体的对象是谁。
  • 当一个对象的数据变化时需要通知其他对象,但它并不需要清楚其他对象的具体变化。

二、设计观察者模式

观察者的 设计类图 如下所示:

在这里插入图片描述

  1. Subject:抽象主题,又称为抽象观察者。把所有观察对象(监听者)保存到一个集合中,可以使用容器保存。提供注册,删除,通知三个接口。
  2. ConcreteSubject:具体主体,又称为观察者,继承抽象主题得到,实现三个接口。
  3. Obsever:抽象观察对象,又称为监听者。提供了处理事件的接口。
  4. ConcreteObsever:具体观察对象,又称为监听者,继承Obsever得到,实现处理事件具体功能

在观察者中保存监听者,采用map键值保存<事件,感兴趣的监听者>,是1-多的关系,可以将其转换为<1,一个监听者集合(可以使用vector存储)>,变为了1-1的关系,表示了哪些监听者对事件感兴趣。

三、实例

观察者监听三个监听者,监听者1对事件1,2感兴趣;监听者2对事件2,3感兴趣;监听者3对事件1,3感兴趣。对类之间的设计如下:

在这里插入图片描述
观察者类需要提供成员函数:

【1. 注册事件函数:】 将<事件-监听者>进行注册,采用容器vector保存监听者集合。假如现在注册1号事件的监听者,那么有两种情况:1号事件被注册,1号事件未注册;

  • 故先在vector集合中查找是否存在1号事件,存在直接将事件插入vector集合即可。
  • 不存在,先开辟集合,将事件放入集合,将集合插入map中。

【通知监听者处理事件】

  1. 先查找是否在map中存在对它感兴趣的事件,存在,提供迭代器遍历监听者集合,调用监听者处理事件函数。
  2. 不存在,打印错误信息。

提供私有成员变量:map, 将事件-监听者集合放入map中,集合用vector存储,存储监听者抽象类指针,可以用基类指针指向派生类对象,访问任意监听者。

监听者类:提供处理函数即可:对自己感兴趣的事件进行处理,进行一个简单的打印。

那么代码如下:

# include<iostream>
# include<deque>
# include<vector>
# include<list>
# include<algorithm>
# include<iterator>
# include<set>
# include<map>
# include<string>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值