《Head First 设计模式》例子的C++实现(2 观察者模式)
最近在学习设计模式,用的是 《Head First 设计模式》这本书。感觉这本书写的还是很不错的,深入浅出的介绍了各种常用的设计模式。唯一有点不方便的地方是这本书的例子全都是用的 Java 来实现的。而我主要是用 C++。所以就动手将书上的代码用 C++ 来实现了一遍。
观察者模式
首先是三个接口的代码:
//observer.h
#ifndef OBSERVER_H
#define OBSERVER_H
class Observer
{
public:
Observer() {}
virtual void update(double temp, double humidity, double pressure) = 0;
};
#endif // OBSERVER_H
//Subject.h
#ifndef SUBJECT_H
#define SUBJECT_H
#include "observer.h"
#include <QList>
class Subject
{
public:
Subject();
void registerObserver(Observer *o);
void removeObserver(Observer *o);
void notifyObservers();
private:
QList<Observer *> m_list;
protected:
double m_temp;
double m_humidity;
double m_pressure;
};
#endif // SUBJECT_H
#include "subject.h"
Subject::Subject()
{
}
void Subject::registerObserver(Observer *o)
{
m_list.append(o);
}
void Subject::removeObserver(Observer *o)
{
int i = m_list.indexOf(o);
if( i >= 0 )
{
m_list.removeAt(i);
}
}
void Subject::notifyObservers()
{
foreach (Observer * o, m_list)
{
o->update(m_temp, m_humidity, m_pressure);
}
}
#ifndef DISPLAYELEMENT_H
#define DISPLAYELEMENT_H
class DisplayElement
{
public:
DisplayElement() {}
virtual void display() = 0;
};
#endif // DISPLAYELEMENT_H
下面是 WeatherData 类:
#ifndef WEATHERDATA_H
#define WEATHERDATA_H
#include "subject.h"
class WeatherData : public Subject
{
public:
WeatherData();
void setMeasurements(double t, double h, double p);
void measurementsChanged();
};
#endif // WEATHERDATA_H
#include "weatherdata.h"
WeatherData::WeatherData()
{
}
void WeatherData::setMeasurements(double t, double h, double p)
{
m_temp = t;
m_humidity = h;
m_pressure = p;
measurementsChanged();
}
void WeatherData::measurementsChanged()
{
notifyObservers();
}
最后是四种观察者:
#include "observer.h"
#include "displayelement.h"
class CurrentConditionDisplay : public Observer, public DisplayElement
{
public:
CurrentConditionDisplay();
void display() override;
void update(double temp, double humidity, double pressure) override;
private:
double m_temp;
double m_humidity;
double m_pressure;
};
class ForecastDisplay: public Observer, public DisplayElement
{
public:
ForecastDisplay();
void display() override;
void update(double temp, double humidity, double pressure) override;
private:
double currentPressure = 29.92f;
double lastPressure;
};
class HeatIndexDisplay : public Observer, public DisplayElement
{
public:
HeatIndexDisplay();
void display() override;
void update(double temp, double humidity, double pressure) override;
private:
double m_heatIndex;
double computeHeatIndex(double t, double rh);
};
class StatisticsDisplay: public Observer, public DisplayElement
{
public:
StatisticsDisplay();
void display() override;
void update(double temp, double humidity, double pressure) override;
private:
int m_numReadings;
double m_tempSum;
double m_maxTemp;
double m_minTemp;
};
#include "display.h"
#include <iostream>
using std::cout;
using std::endl;
CurrentConditionDisplay::CurrentConditionDisplay()
{
}
void CurrentConditionDisplay::display()
{
cout << "Current conditions:" << m_temp
<< " F degrees and " << m_humidity
<< "% humidity" << endl;
}
void CurrentConditionDisplay::update(double temp, double humidity, double pressure)
{
m_temp = temp;
m_humidity = humidity;
m_pressure = pressure;
display();
}
ForecastDisplay::ForecastDisplay()
{
}
void ForecastDisplay::display()
{
cout << "Forecast: ";
if (currentPressure > lastPressure)
{
cout << "Improving weather on the way!";
}
else if (currentPressure == lastPressure)
{
cout << "More of the same";
}
else if (currentPressure < lastPressure)
{
cout << "Watch out for cooler, rainy weather";
}
cout << endl;
}
void ForecastDisplay::update(double temp, double humidity, double pressure)
{
lastPressure = currentPressure;
currentPressure = pressure;
display();
}
HeatIndexDisplay::HeatIndexDisplay()
{
}
void HeatIndexDisplay::display()
{
cout << "Heat index is " << m_heatIndex << endl;
}
void HeatIndexDisplay::update(double temp, double humidity, double pressure)
{
(void) pressure;
m_heatIndex = computeHeatIndex(temp, humidity);
display();
}
double HeatIndexDisplay::computeHeatIndex(double t, double rh)
{
double index = (double)((16.923 + (0.185212 * t) + (5.37941 * rh) - (0.100254 * t * rh)
+ (0.00941695 * (t * t)) + (0.00728898 * (rh * rh))
+ (0.000345372 * (t * t * rh)) - (0.000814971 * (t * rh * rh)) +
(0.0000102102 * (t * t * rh * rh)) - (0.000038646 * (t * t * t)) + (0.0000291583 *
(rh * rh * rh)) + (0.00000142721 * (t * t * t * rh)) +
(0.000000197483 * (t * rh * rh * rh)) - (0.0000000218429 * (t * t * t * rh * rh)) +
0.000000000843296 * (t * t * rh * rh * rh)) -
(0.0000000000481975 * (t * t * t * rh * rh * rh)));
return index;
}
StatisticsDisplay::StatisticsDisplay():
m_tempSum(0.0),
m_maxTemp(0),
m_minTemp(200),
m_numReadings(0)
{
}
void StatisticsDisplay::display()
{
cout << "Avg/Max/Min temperature = " << m_tempSum / m_numReadings
<< "/" << m_maxTemp << "/" << m_minTemp << endl;
}
void StatisticsDisplay::update(double temp, double humidity, double pressure)
{
(void) humidity;
(void) pressure;
m_tempSum += temp;
m_numReadings++;
if (temp > m_maxTemp)
{
m_maxTemp = temp;
}
if (temp < m_minTemp)
{
m_minTemp = temp;
}
display();
}
最后是测试代码:
int main(int argc, char *argv[])
{
WeatherData weatherData;
CurrentConditionDisplay currentDisplay;
StatisticsDisplay staticDisplay;
ForecastDisplay forcastDisplay;
HeatIndexDisplay heatDisplay;
weatherData.registerObserver(¤tDisplay);
weatherData.registerObserver(&staticDisplay);
weatherData.registerObserver(&heatDisplay);
weatherData.registerObserver(&forcastDisplay);
weatherData.setMeasurements(80, 65, 30.4);
weatherData.setMeasurements(82, 70, 29.2f);
weatherData.setMeasurements(78, 90, 29.2f);
}
《Head First 设计模式》例子的C++实现(2 观察者模式)的更多相关文章
- Java 设计模式系列(十五)观察者模式(Observer)
Java 设计模式系列(十五)观察者模式(Observer) Java 设计模式系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Java ...
- php 设计模式 例子
加载类:include("./Ren.class.php");include "./Ren.class.php"; require("./Ren.cl ...
- js设计模式中发布与订阅实现观察者模式例子
<script> var pubsub = {}; (function(q) { var topics = {}; subuid = -1; q.publish = function(to ...
- 学C#之设计模式系列笔记(2)观察者模式
一.借鉴说明 1.<Head First Design Patterns>(中文名<深入浅出设计模式>) 2.维基百科,观察者模式,https://zh.wikipedia.o ...
- Java设计模式(四)——再谈观察者模式
在本系列的上一篇文章中,我们讨论了JDK对于观察者模式的一套实现.今天我们将要从另一个角度来探索Tomcat中是如何利用观察者模式加载各个组件.不过今天的任务不是解释Tomcat,所以我会单独把重点抽 ...
- JAVA设计模式详解(二)----------观察者模式
有一个模式可以帮助你的对象知悉现况,不会错过该对象感兴趣的事,对象甚至在运行时可以决定是否要继续被通知,如果一个对象状态的改变需要通知很多对这个对象关注的一系列对象,就可以使用观察者模式 .观察者模式 ...
- [转] JavaScript设计模式之发布-订阅模式(观察者模式)-Part1
<JavaScript设计模式与开发实践>读书笔记. 发布-订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖它的对象都将得到通知. 例如 ...
- Java设计模式之(十二)——观察者模式
1.什么是观察者模式? Define a one-to-many dependency between objects so that when one object changes state, a ...
- Java设计模式菜鸟系列(两)建模与观察者模式的实现
转载请注明出处:http://blog.csdn.net/lhy_ycu/article/details/39755577 观察者(Observer)模式定义:在对象之间定义了一对多的依赖关系,这样一 ...
- 设计模式一:关于C++写观察者模式的一些收获
先贴上部分代码: #include "stdafx.h" #include<iostream> #include<string> #include<v ...
随机推荐
- aws s3文件上传设置accesskey、secretkey、sessiontoken
背景: 最近跟进的项目会封装aws S3资源管理细节,对外提供获取文件上传凭证的API,业务方使用获取到的凭证信息直接请求aws进行文件上传.因此,测试过程需要验证S3文件上传的有效性.aws官网有提 ...
- Python之SGDRegressor
实现: # -*- coding: UTF-8 -*- import numpy as npfrom sklearn.linear_model import SGDRegressor __author ...
- python3 下列表与字典转换
在写爬虫的时候,经常需要处理cookie,requests库里的cookie是dict,但是headers['cookie']却是一个key=value的字符串. 下面是几个用推导式实现的转换函数,供 ...
- 字符串相似度算法-LEVENSHTEIN DISTANCE算法
Levenshtein Distance 算法,又叫 Edit Distance 算法,是指两个字符串之间,由一个转成另一个所需的最少编辑操作次数.许可的编辑操作包括将一个字符替换成另一个字符,插入一 ...
- zabbix监控磁盘IO
我这里有两种方法,感觉都不错.我这里主要是写一下监控的脚本. 1.使用iostat命令监控 1)首先打开配置文件的自定义脚本功能,然后编写脚本. #!/bin/bash ];then echo &qu ...
- nginx代理 upstream轮询
问题描述 我有2个Tomcat 一个端口开启(8021),一个端口未开启(8022),在nginx里用upstream模块进行代理 ,代理的负载算法采用的是默认的轮询算法,配置成功后,访问页面时并没 ...
- Linux 小知识翻译 - 「内核(kernel)」
上次介绍了Linus Torvalds, 这次介绍他开发的「内核」. 经常听人提到「Linux kernel」,但如果被问到「kernel究竟是什么?」的话,会出乎意料的觉得难以回答. 那么,kern ...
- MATLAB数值积分法
MATLAB数值积分法 作者:凯鲁嘎吉 - 博客园http://www.cnblogs.com/kailugaji/ 一.实验目的 许多工程技术和数学研究中要用到定积分,如果无法直接算不出精确值(如含 ...
- book118免费下载文档方法【转】
需要用的工具: 1.360浏览器 2.点"全屏预览",然后把鼠标放在"下载该文档",右键"审查元素",找到 途中箭头指向的标签(如图) 3. ...
- 【BZOJ2159】Crash的文明世界
[2011集训贾志鹏]Crash的文明世界 Description Crash小朋友最近迷上了一款游戏--文明5(Civilization V).在这个游戏中,玩家可以建立和发展自己的国家,通过外交和 ...