设计模式之二:观察者模式

news2024/11/16 5:23:38

假定我们需要为Weather-O-Rama公司建立一个气象站系统,除已有的WeatherData有数据源类,还需要更新三个布告板的显示:目前状况(温度、湿度、气压)、气象统计和天气预报。

 1 以下是一个可能的实现

class WeatherData
{
private:
	//实例变量声明

public:
	void measurementsChanged()
	{
		float temp = getTemperature();
		float humidity = getHumidity();
		float pressure = getPressure();

		currentConditionsDisplay.update(temp, humidity, pressure);
		statisticsDisplay.update(temp, humidity, pressure);
		forecastDisplay.update(temp, humidity, pressure);
	}

	float getTemperature() {}
	float getHumidity() {}
	float getPressure() {}
};

上述实现有以下问题存在:

  • 针对具体实现编程,而非针对接口(currentConditionsDisplay都是具体的实例)
  • 针对每个新的布告板,都得修改代码(添加新的布告板到代码中)
  • 无法在运行时动态增删布告板
  • 尚未封装改变的部分(调用几个update的地方)

2 观察者模式

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

主题是具有状态的对象,并且可以控制这些状态。另一方面,观察者使用这些状态,虽然这些状态不属于他们。

观察者模式提供了一种对象设计(设计原则:为了交互对象之间的松耦合设计而努力),让主题和观察者之间松耦合。

主题只知道观察者实现了某个接口,并不需要知道具体的观察者是谁,做了什么动作。同时,我们也可以在运行时增删观察者。

class Subject
{
public:
	virtual void registerObserver(Observer o) = 0;
	virtual void removeObserver(Observer o) = 0;
	virtual void notifyObserver() = 0;
};

class Observer
{
public:
	virtual void update(float temp, float humidity, float pressure) = 0;
};

class DisplayElement
{
public:
	virtual void display() = 0;
};

// WeatherData实现接口

class WeatherData : public Subject
{
private:
	std::vector<Observer*> observers;
	float temprature;
	float humidity;
	float pressure;

public:
	WeatherData()
	{
		observers = new vector<Observer*>();
	}

	void registerObserver(Observer* o)
	{
		observers.add(o);
	}

	void removeObserver(Observer* o)
	{
		observers.remove(o);
	}

	void notifyObserver()
	{
		for (Observer* o : observers)
		{
			o->update(temprature, humidity, pressure);
		}
	}

	void measurementsChanged()
	{
		notifyObserver();
	}
};
// 布告板实现Observer接口

// 为什么要保存对Subject的引用呢,构造完后好像并未使用?
// 以后可能想要取消注册,如果有对Subject的引用会比较方便。

class CurrentConditionsDisplay : public Observer, DisplayElement
{
private:
	Subject* weatherData;
	float temprature;
	float humidity;

public:
	CurrentConditionsDisplay(Subject* weatherData)
	{
		this->weatherData = weatherData;
		weatherData->registerObserver(this);
	}

	void update(float temp, float humidity, float pressure)
	{
		this->temprature = temp;
		this->humidity = humidity;
		display();
	}

	void display()
	{
		std::cout << "Temprature:" << temprature << "Humidity:" << humidity << std::endl;
	}
};

除使用上面的“推”方式主动将数据传送给观察者,还可以通过“拉”方式主动拉取数据(可以传递一个主题对象,或者数据对象给update方法,或者从私有变量中提取)。

// 主题本身作为变量,可以让观察者知道是哪个主题通知的
update(Observer o) {}

// Java的内置实现有setChanged()方法,可以在更新观察者时具有更多的弹性,比如什么时候可以
// 不更新,什么时候更新

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/738433.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

雅思口语备考模仿练习有没有用?

如何对于雅思口语进行模仿练习&#xff1f;这是很多同学需要了解的事情&#xff0c;那么接下来就和一起来了解一下雅思口语备考模仿练习有没有用&#xff1f; 模仿练习 1. 方法 众所周知&#xff0c;模仿最基本的方法便是跟读。跟读的途径可以是两种&#xff1a;一种是听录音…

【AcWing算法基础课】第四章 数学知识(未完待续)

文章目录 前言课前温习番外&#xff1a;秦九韶算法核心模板 一、质数1. 试除法判定质数核心模板1.1题目描述1.2思路分析1.3代码实现 2、试除法分解质因数核心模板1.4题目描述1.5思路分析1.6代码实现 二、筛素数1.朴素筛法求素数核心模板2.线性筛法求素数&#xff08;O(n)&#…

寻找nacos数据库连接名及密码

首先找到resources下的bootstrap.properties 找到其中的 spring.cloud.nacos.username***** spring.cloud.nacos.password**** 这个为nacos登陆的密码 到nacos中找到相应服务配置信息 spring.datasource.druid.urljdbc:mysql://ip地址 spring.datasource.druid.username用户…

防水防尘防震的工业三防平板电脑

工业三防平板电脑是一种具有防尘、防水和防震功能的平板电脑。它们被广泛应用于工业领域&#xff0c;特别是在恶劣环境下的工作场所。这些平板电脑具有坚固耐用的外壳和先进的技术&#xff0c;能够在恶劣的工作条件下提供稳定可靠的性能。 工业三防平板电脑的功能&#xff1a; …

Docker私有仓库搭建与界面化管理

一、关于Registry 官方的Docker hub是一个用于管理公共镜像的好地方&#xff0c;我们可以在上面找到我们想要的镜像&#xff0c;也可以把我们自己的镜像推送上去。 但是有时候我们的使用场景需要我们拥有一个私有的镜像仓库用于管理我们自己的镜像。这个可以通过开源软件Regi…

分享AIGC前沿论文系列二 面向区域级图像理解的端到端多模态大模型GPT4RoI

文章目录 概要论文摘要论文细节获取方式 概要 面向区域级图像理解的端到端多模态大模型 带来了超越图像级理解的全新对话和交互体验 进行丝滑的人机互动&#xff0c;不仅仅是文字级别的人机互动 论文摘要 本文提出对感兴趣区域进行Instruction Tuning&#xff0c;并提出GPT4…

Django基础入门⑬:Django表单实例【表单应用】获取全量书籍信息

Django基础入门⑫&#xff1a;Django 对象查询详解&#xff0c;分组聚合 Django表单实例表单应用编写模板层HTML页面编写视图层逻辑代码配置url路由模式映射页面搜索效果展示表单验证逻辑 获取全量书籍信息实现添加书籍信息 &#x1f3d8;️&#x1f3d8;️个人简介&#xff1a…

jmeter的高阶使用技巧——打印时间戳与年月时分秒

Jmeter中提供了一种函数&#xff0c;可以打印时间戳&#xff0c;如下图 年&#xff1a; yyyy 月&#xff1a;MM 日&#xff1a;dd   时&#xff1a; HH 分&#xff1a; mm 秒&#xff1a;ss 关于时间戳的格式&#xff0c;可以自由组合定义&#xff0c;这里我写成这样 yyyy-M…

443端口被占用,vmware居然也来捣乱

今天搬砖时发现应用起不来了&#xff0c;显示出了熟悉的error *************************** APPLICATION FAILED TO START ***************************~~重点在这块哈 Description:Web server failed to start. Port 443 was already in use.Action:Identify and stop the p…

共创先进软件,驱动装备数字化——同元软控成功举办MWORKS 2023b产品发布会

6月30日&#xff0c;MWORKS 2023b产品发布会与Modelica暨装备数字化研讨会&#xff08;2023&#xff09;同期举行。继2023年1月8日发布MWORKS 2023a之后&#xff0c;年内第二个版本如期而至。MWORKS是苏州同元软控信息技术有限公司&#xff08;简称“同元软控”&#xff09;历时…

IPO观察丨烧钱7年、押注新药上市,来凯医药正在经历一场关键突围

医药板块的加速回升趋势越来越显著。据Choice数据显示&#xff0c;截至7月6日&#xff0c;7月以来医药相关ETF合计获净申购37.17亿份。拉长期限来看&#xff0c;2023年以来医药相关ETF合计获净申购637.06亿份。根据区间成交均价计算&#xff0c;今年以来有超300亿元资金流入医药…

DAY43:不同路径+不同路径Ⅱ(初始化注意点很多,及时复盘)

文章目录 62.不同路径&#xff08;注意初始化&#xff09;BFS深度搜索写法动态规划思路DP数组的含义递推公式DP数组初始化遍历顺序打印dp数组 动态规划写法数组越界的问题for循环执行的问题 63.不同路径Ⅱ&#xff08;初始化区别&#xff09;思路DP数组含义递推公式DP数组初始化…

武汉理工大学信息工程学院2023暑期学术夏令营|信息与通信工程方向

目录 武汉理工大学 校训&#xff1f; 1 通信系统的有效性和可靠性 2 关于QAM调制的问题 2.1 什么是调制 2.2 什么是载波调制 2.3 QAM原理 2.4 数字信号QAM调制 2.5 QAM如何实现&#xff1f; 3 看马路上行驶的车辆轮胎为什么倒转 “视觉暂留” 4 6G/4G/5G的经典技…

卫星数据下载指南

1、USGS Earth Explorer&#xff08;美国地质勘探局地球探测器&#xff09; EarthExplorer 2、Sentinel Open Access Hub https://scihub.copernicus.eu/dhus/#/home 3、NASA Earthdata Search&#xff08;美国航天局地球数据搜索&#xff09; https://search.earthdata.n…

构建新型电力系统,需要什么样的数字能源底座?

在迈向“碳中和”的进程中&#xff0c;全球能源产业变革已经进入了关键时期&#xff0c;其中电力系统的价值从未像今天这样重要。 国际能源署数据显示&#xff0c;2022年全球与能源相关的二氧化碳排放量超过368亿吨&#xff0c;创下历史新高。其中&#xff0c;电力领域碳排放占…

什么是热修复?它的优缺点是什么?

我们开发时常常要考虑的一些问题。 开发上线的版本能保证不存在Bug么&#xff1f; 修复后的版本能保证用户都及时更新么&#xff1f; 如何最大化减少线上Bug对业务的影响&#xff1f; 热修复技术帮助我们解决了很多问题&#xff0c;带来的优势不言而喻。不知道各位对于热修复技…

Qt关于mqtt多平台移植

最近写了很多mqtt相关的项目&#xff0c;但是在各个平台上编译mqtt的库成为了一个很麻烦的事情&#xff0c;每个平台都需要去编译一次&#xff0c;而且还会出现各种问题&#xff0c;为了方便解决这个问题&#xff0c;所以这里将mqtt库的代码以源代码的方式添加进去&#xff0c;…

Kafka 基础概念学习

基础概念学习 一.基础概念二.结构图 一.基础概念 Kafka 基本概念&#xff1a;一种分布式的&#xff0c;基于发布/订阅的消息系统项目ValueBrokerKafka服务端(即部署了Kafka的机器)Producer生产者写数据到主副本Consumer消费者从主副本读数据Consumer Group消费者组&#xff0c…

Apache Doris (二十二) :Doris Rollup物化索引作用及使用注意点

目录 1. Rollup 物化索引作用 1.1 改变索引 1.2 聚合数据 ​​​​​​​2. Rollup物化索引注意点 进入正文之前&#xff0c;欢迎订阅专题、对博文点赞、评论、收藏&#xff0c;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; 宝子们点赞、收藏不迷路&#xff01;…

Stable Diffusion - 图像控制插件 ControlNet (OpenPose) 配置与使用

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/131591887 论文&#xff1a;Adding Conditional Control to Text-to-Image Diffusion Models ControlNet 是神经网络结构&#xff0c;用于控制预…