观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖着都会收到通知并自动更新。

当两个对象之间松耦合,他们依然可以交互,但是不太清楚彼此的细节。观察者模式提供了一种对象设计,让主题和观察者之间松耦合。我们可以独立复用主题和观察者,如果我们在其他地方需要使用主题或观察者,可以轻易地复用,因为二者并非紧耦合。改变主题或者观察者其中一方,并不会影响另一方。因为两者是松耦合的,所以只要他们之间的接口仍被遵守,我们就可以自由地改变他们。

松耦合的设计之所以能让我们建立有弹性的OO系统,能够应对变化,是因为对象之间的互相依赖降到了最低。

书上的例子是一个天气公告牌,代码如下:

Weather.h

#include <vector>
#include <string> class Observer {
public:
virtual void update(float temp) = 0;
}; class DisplayElement {
public:
virtual void display() = 0;
}; class Subject {
public:
virtual void registerObserver(Observer& o) = 0;
virtual void removeObserver(Observer& o) = 0;
virtual void notifyObservers() = 0;
}; class WeatherDate : public Subject {
public:
~WeatherDate();
void registerObserver(Observer& o);
void removeObserver(Observer& o);
void notifyObservers();
void measurementsChanged();
void setMeasurements(float temp);
private:
std::vector<Observer*> observerList;
float temperature = 0;
}; class WeatherBoard01: public Observer, DisplayElement {
public:
WeatherBoard01(Subject& weatherDate, std::string name);
~WeatherBoard01();
void update(float temp);
void display();
private:
std::string name = "";
float temperature = 0;
Subject* weatherDate = nullptr;
}; void weatherTest();

Weather.cpp

#include <iostream>
#include "Weather.h" WeatherDate::~WeatherDate() {
for (auto it: observerList) {
delete it;
}
} void WeatherDate::registerObserver(Observer &o) {
observerList.push_back(&o);
} void WeatherDate::removeObserver(Observer &o) {
for (auto it = observerList.begin(); it != observerList.end(); it++) {
if (*it == &o) {
observerList.erase(it);
break;
}
}
} void WeatherDate::notifyObservers() {
for (auto it: observerList) {
it->update(temperature);
}
} void WeatherDate::measurementsChanged() {
notifyObservers();
} void WeatherDate::setMeasurements(float temp) {
temperature = temp;
measurementsChanged();
} WeatherBoard01::WeatherBoard01(Subject &weatherDate, std::string name) {
this->weatherDate = &weatherDate;
this->name = name;
weatherDate.registerObserver(*this);
weatherDate.notifyObservers();
} WeatherBoard01::~WeatherBoard01() {
delete weatherDate;
} void WeatherBoard01::update(float temp) {
temperature = temp;
display();
} void WeatherBoard01::display() {
std::cout<<"WeatherBoard01("<<name<<"): "<<temperature<<std::endl;
}

需要注意的东西大概:

1. 如果类成员变量是指针vector,应该如何析构?

2. 抽象类不能直接作为函数的参数。那么是传引用更好还是传指针更好?

3. vector的方法待学习。

blog的观察者模式实现了一个博客和订阅者的关系,具体见:https://blog.csdn.net/wuzhekai1985/article/details/6674984

两者区别在于:

1. blog里的代码没有具体实现析构函数。但是对于有指针成员的类,应该手动delete。所以还是不知道指针vector怎么析构。

2. 一个好的思路:观察者对主题的指针也可以设计成指针vector,这样的话就允许一个观察者同时观察多个主题,把一对多的关系扩展为多对多的关系。

设计模式c++(3)——观察者模式的更多相关文章

  1. 设计模式 ( 十六 ) 观察者模式Observer(对象行为型)

    设计模式 ( 十六 ) 观察者模式Observer(对象行为型) 1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来 ...

  2. Java设计模式之《观察者模式》及应用场景

    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6513651.html 观察者模式,又可以称之为发布-订阅模式,观察者,顾名思义,就是一个监 ...

  3. Java设计模式百例 - 观察者模式

    观察者(Observer)模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,主体对象的状态变化会通知所有观察者对象.观察者模式又叫做发布-订阅(Publish/Subscribe ...

  4. [head first 设计模式]第二章 观察者模式

    [head first 设计模式]第二章 观察者模式 假如我们有一个开发需求--建造一个气象观测站展示系统.需求方给我们提供了一个WeatherObject对象,能够自动获得最新的测量数据.而我们要建 ...

  5. Java设计模式10:观察者模式

    观察者模式 观察者模式也叫作发布-订阅模式,也就是事件监听机制.观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态上发生变化时,会通知所有观察者对象,使他 ...

  6. 大话设计模式C++版——观察者模式

    观察者模式是一种类似于消息分发的模式,用于一个任务需要被多个对象监听的场景,或者成员对象需要反向通知类对象的情况,是一种很有用的设计模式.    这里以大话设计模式中的例子为例,办公室员工A.B.C在 ...

  7. 【C++深入浅出】设计模式学习之观察者模式

    前言 前两天学习了weak_ptr以后还是不甚明了,一则需要实际应用去锤炼,二来就是不懂观察者模式. 正文 观察者模式又叫发布-订阅模式,定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对 ...

  8. php设计模式之:观察者模式

    转载自php面向对象设计模式 之 观察者模式 问题 假如一个小贩, 他把产品的价格提升了, 不同的消费者会对此产生不同的反应.一般的编程模式无非是获取提升的价格,然后获取所有的消费者,再循环每个消费者 ...

  9. 我理解设计模式C++实现观察者模式Observer Pattern

    概述: 近期中国股市起起伏伏,当然了起伏就用商机,小明发现商机后果断想入市,买入了中国证券,他想在电脑client上,网页上,手机上,iPad上都能够查看到该证券的实时行情,这样的情况下我们应该怎么设 ...

  10. 设计模式学习之“观察者模式” [C#]

    <深入浅出设计模式>学习笔记第二章 需求: 开发一套气象监测应用,如图: 气象站,目前有三种装置,温度.湿度和气压感应装置. WeatherData对象追踪气象站的数据,并更新到布告板,布 ...

随机推荐

  1. 决胜面试之---SQL经典面试题

    在SQL面试部分,一般会考核多表连接查询能力,精选了一些SQL面试题记录下: 四张表(学生表,教师表,课程表,成绩表)                       以下是表的创建和添加SQL语句 学生 ...

  2. Java通过jni调用动态链接库

    (1)JNI简介 JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++).从Java1.1开始,JNI标准成为java ...

  3. ES6 Set.Map.Symbol数据结构

    一.ES6 Set数据结构 ES6新推出了Set数据结构,它与数组很类似,Set内部的成员不允许重复,每一个值在Set中都是唯一的,如果有重复的值出现会自动去重(也可以理解为忽略掉),返回的是集合对象 ...

  4. spark:distinct算子实现原理

    distinct的底层使用reducebykey巧妙实现去重逻辑 //使用reduceByKey或者groupbykey的shuffle去重思想rdd.map(key=>(key,null)). ...

  5. linux下安装docker容器

    1.安装环境 此处在Centos7进行安装,可以使用以下命令查看CentOS版本 lsb_release -a 在 CentOS 7安装docker要求系统为64位.系统内核版本为 3.10 以上,可 ...

  6. Angular入门到精通系列教程(7)- 组件(@Component)基本知识

    1. 概述 2. 创建Component 组件模板 视图封装模式 特殊的选择器 :host inline-styles 3. 总结 环境: Angular CLI: 11.0.6 Angular: 1 ...

  7. servlet+jsp完成简单登录

    将用户在注册界面中的数据填充到数据库相对应的表格中.当用户再次登录时,从数据库中拿到相应的数据查询并与页面的数据做对比,判断是否登陆成功. 需要在HTML文件中将form表单上的action属性值设置 ...

  8. Ubuntu 18.04.4 系统优化

    1 ) 允许root远程登录: sudo apt install vim git net-tools openssh-server sudo vim /etc/ssh/sshd_config .... ...

  9. FAT32、NTFS、exFAT有什么区别?

    文件系统 我们经常会对电脑硬盘.U盘.移动硬盘进行格式化,而在格式化硬盘的时候会弹出文件系统的选项,分别有FAT32.NTFS.exFAT三种格式,那么FAT32.NTFS.exFAT有什么区别? 在 ...

  10. MyBatis初级实战之三:springboot集成druid

    OpenWrite版: 欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kuber ...