代码写的不够规范,目的是缩短篇幅,实际情况请不要这样做

1、概述

  观察者模式,类比生活中的场景,比如看电影,观众对播放的内容有不同的反应, 再比如订阅,公众号订阅,只要你订阅了其公众号,你就会收到其推送。再比如,天气,人们针对天气变化的反应也是不一样的。

  观察者模式的主要角色如下。
  A、抽象主题角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
  B、具体主题角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
  C、抽象观察者角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
  D、具体观察者角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。

  总结,主要2个对象: 观察者和被观察对象。

2、观察者抽象类

// 观察者
class observer
{
public:
// 观察者的反应
virtual void respond() = 0;
};

3、观察者类

  这里,准备了两个观察者,

// 观察者A
class observerA : public observer
{
public:
void respond()
{
std::cout << "\n观察者A做出反应\n";
}
}; // 观察者B
class observerB : public observer
{
public:
void respond()
{
std::cout << "\n观察者B做出反应\n";
}
};

4、抽象对象(目标)

// 抽象目标
class subject
{
public:
// 添加新的观察者
virtual void add(observer *pobs)
{
if (!pobs)
return; std::list<observer*>::iterator it = std::find(_plist_observer.begin(), _plist_observer.end(), pobs); // 没有找到,则添加
if (it == _plist_observer.end())
_plist_observer.push_back(pobs);
else
cout << "\n对象已经存在,无需重复添加\n"; } // 删除观察者
virtual void remove(observer *pobs)
{
if (!pobs)
return; int size = _plist_observer.size();
if (0 < size)
_plist_observer.remove(pobs);
} // 通知所有观察者
virtual void notify_observer() = 0; protected:
// 可能有多个观察者
std::list<observer*> _plist_observer;
};

5、具体目标类

// 对象A,
class subjectA :public subject
{
public:
// 实现,并通知观察者
void notify_observer()
{
std::cout << "\n\n\n-----请注意,目标A已经变化了----\n";
for each (auto item in _plist_observer)
item->respond();
}
};

6、调用示例

 1 // 调用
2 void call_observer()
3 {
4 // 1、创建观察者 和 被观察的目标
5 std::unique_ptr<observer> pobsA(new(std::nothrow) observerA);
6 std::unique_ptr<observer> pobsB(new(std::nothrow) observerB);
7 std::unique_ptr<subject> psubA(new(std::nothrow) subjectA);
8
9 if (!pobsA || !pobsB || !psubA)
10 {
11 std::cout << "\n 创建观察者或者目标失败\n\n";
12 return;
13 }
14
15 // 2、被观察目标添加观察者
16 psubA->add(pobsA.get());
17 psubA->add(pobsB.get());
18 std::cout << "1、目标变化了,观察者反应:";
19 psubA->notify_observer();
20
21 // 3、解除观察者
22 psubA->remove(pobsA.get());
23 std::cout << "\n\n2、解除观察者A,目标变化,观察者反应";
24 psubA->notify_observer();
25 }

7、输出

最新文章

  1. Lattice Diamond 学习之编译、检查和设置约束
  2. php会话(session)生命周期概念介绍及设置更改和回收
  3. 通过FTP将一个数据文件从A服务器下载到B服务器的整个过程
  4. C与OC、C++的区别
  5. IE浏览器下读取客户端上传的文件大小
  6. String.format Tutorial
  7. LeetCode(66): 加一
  8. mybatis的插件分析
  9. Windows10 下Apache服务器搭建
  10. javaScript+html5实现图片拖拽
  11. 针对需要使用T3协议的Weblogic2628漏洞解决方案
  12. 3、Sql-Ora-01033:oracle initialization or shutdown in progress
  13. time random sys os 模块
  14. Maven 标签
  15. Bootstrap in ASP.NET MVC 5
  16. 20172319 《Java程序设计教程》第7周学习总结
  17. 工具推荐. 在线unix, 在线python/perl脚本测试环境
  18. sqlmap的使用方法 ——时光凉春衫薄
  19. 设置两个WdatePicker的开始时间小于结束时间,结束时间大于开始时间
  20. TWebBrowser: Determine when a page with Frames is completed

热门文章

  1. Mysql优化,ICP、BNL算法、BKA算法、MMR算法
  2. kubernetes 用到的工具及组件
  3. TensorFlow 2.0 深度学习实战 —— 浅谈卷积神经网络 CNN
  4. Hadoop【MR的分区、排序、分组】
  5. 大数据学习day38----数据仓库01-----区域字典的生成
  6. 【leetcode】797. All Paths From Source to Target
  7. SpringBoot让测试类飞起来的方法
  8. 使用IntelliJ IDEA创建简单的Spring Boot项目
  9. 使用JSP实现输出
  10. ANTLR 相关术语