观察者模式
时间:2022-04-26
本文章向大家介绍观察者模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一、简介
1、观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象。这个主题对象在状态发生变化的时候,会通知所有观察者对象,使它们能够动态的更新自己。
如:图形界面的工具箱中,表格对象和柱状图对象使用不同的形式描述同一应用数据对象的信息。表格对象和柱状图对象相互并不知道对方的存在,但是当用户改变表格中的信息的时候,柱状图也应该立即反映这一变化,反过来也如此。这意味着表格对象和柱状图对象都依赖于数据对象,数据对象的任何改变都应该立即通知它们。所以这个例子中表格和柱状图就是两个观察者,而数据对象就是被观察的主题。
2、模式中的角色
抽象主题(Subject):它把所有观察者对象的引用保存到一个List,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
3、UML
4、所属类别:行为型
二、C++程序
下面以老师上课点名为例写一个观察者的程序,小尹和小胥两位同学都要一个去上课的同学帮忙老师是否点名,如果点名了就跑去上课,否则泡实验室学习。
1 // 观察者模式.cpp : 定义控制台应用程序的入口点。
2 //
3
4 #include "stdafx.h"
5 #include<iostream>
6 #include <list>
7 #include<string>
8 using namespace std;
9 class Observer
10 {
11 public:
12 Observer(){}
13 virtual ~Observer(){}
14 virtual void update(){}
15 };
16 //抽象主题
17 class Subject
18 {
19 private:
20 typedef list<Observer* >LIST; //观察者链表
21 LIST observers;
22 protected:
23 string subjectstate;
24 public:
25 Subject(){}
26 virtual ~Subject(){}
27 void add_observer(Observer *observer) //添加观察者
28 {
29 observers.push_back(observer);
30 }
31 void remove_observer(Observer *observer)//删除观察者
32 {
33 observers.remove(observer);
34 }
35 virtual void set_subjectstate(string )=0;//设置当前主题的状态
36 virtual string get_subjectstate()=0;//观察当前主题的状态
37 void notify()
38 {
39 LIST::iterator node = observers.begin();
40 for(; node != observers.end(); node++)
41 {
42 (*node)->update();
43 }
44 }
45 };
46
47 class Concretesubject:public Subject
48 {
49 public:
50 Concretesubject (){}
51 virtual~Concretesubject (){}
52 virtual void set_subjectstate(string s)
53 {
54 subjectstate=s;
55 }
56 virtual string get_subjectstate()
57 {
58 return subjectstate;
59 }
60 };
61
62 class Concereteobserver:public Observer
63 {
64 private:
65 Subject * subject;
66 public:
67 Concereteobserver(Subject *s)
68 {
69 subject=s;
70 }
71 ~Concereteobserver(){}
72 void update()
73 {
74 string state=subject->get_subjectstate();
75 if(state=="点名了")
76 {
77 cout<<"赶紧跑去上课"<<endl;
78 }
79 if(state=="正常上课")
80 {
81 cout<<"继续泡实验室"<<endl;
82 }
83 }
84 };
85 int _tmain(int argc, _TCHAR* argv[])
86 {
87 //创建一个具体的主题,上课老师是否点名
88 Subject *dianming=new Concretesubject();
89 //创造两个人 小尹和小胥
90 Observer * xiaoyin=new Concereteobserver(dianming);
91 Observer * xiaoxu=new Concereteobserver(dianming);
92 //将小尹和小胥两个人注册为该主题的观察者
93 dianming->add_observer(xiaoyin);
94 dianming->add_observer(xiaoxu);
95 //该主题发生变化的时候,自动通知他们,然后他们采取措施
96 dianming->set_subjectstate("点名了");
97 dianming->notify();
98 return 0;
99 }
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- python3 常用的时间工具学习笔记
- Cypress端到端自动化测试学习笔记
- python常用文本串处理库学习笔记
- python+locust性能测试学习笔记
- 为什么编译原理被称为龙书?
- 用好Jackson,操作Json节省一半时间
- Java|类的继承中两种错误的解决方式 |案例介绍
- 3分钟短文 | PHP时不时蹦出这串神秘字符,有认识的吗?
- 五分钟看懂 Nginx 负载均衡
- 干掉公式 —— numpy 就该这么学
- 全面解析YOLO V4网络结构
- 刺激!一行代码即可导出所有浏览记录
- 你不知道的 node 爬虫原来这么简单
- 带货直播系统源码中,商品详情页是如何搭建起来的
- 基于飞桨复现CVPR 2020 GhostNet的全程解析