最近在学习设计模式,用的是 《Head First 设计模式》这本书。感觉这本书写的还是很不错的,深入浅出的介绍了各种常用的设计模式。唯一有点不方便的地方是这本书的例子全都是用的 Java 来实现的。而我主要是用 C++。所以就动手将书上的代码用 C++ 来实现了一遍。

观察者模式

首先是三个接口的代码:

//observer.h
#ifndef OBSERVER_H
#define OBSERVER_Hclass 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_Hclass 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(&currentDisplay);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 观察者模式)相关推荐

  1. c语言 适配器模式例子,NodeJS设计模式总结【单例模式,适配器模式,装饰模式,观察者模式】...

    NodeJS设计模式总结[单例模式,适配器模式,装饰模式,观察者模式] 发布时间:2020-08-21 03:08:03 来源:脚本之家 阅读:117 作者:lucky芬 本文实例讲述了NodeJS设 ...

  2. 设计模式C++实现(15)——观察者模式

    观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.它还有两个别名,依赖(Dependents),发布-订阅(Publish-Subsr ...

  3. 设计模式C++实现(7)——观察者模式

    观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.它还有两个别名,依赖(Dependents),发布-订阅(Publish-Subsr ...

  4. JavaScript设计模式之发布-订阅模式(观察者模式)-Part1

    <JavaScript设计模式与开发实践>读书笔记. 发布-订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖它的对象都将得到通知. 例如 ...

  5. 装饰模式(大话设计模式例子C++实现)

    1 概述 装饰模式:动态地给一个对象添加一些额外的职责.就增加功能来说,装饰模式相比生成子类更为灵活.有时我们希望给某个对象而不是整个类添加一些功能.比如有一个电脑(人),允许你为电脑添加特性,比如添 ...

  6. 设计模式之装饰者模式及观察者模式

    装饰器模式: 装饰器模式(Decorator Pattern)(包装)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装.这种模式创建了 ...

  7. Java设计模式(访问者模式-迭代器模式-观察者模式-中介者模式)

    Java设计模式Ⅶ 1.访问者模式 1.1 访问者模式概述 1.2 代码理解 2.迭代器模式 2.1 迭代器模式概述 2.2 代码理解 3.观察者模式 3.1 观察者模式概述 3.2 代码理解 4.中 ...

  8. python的编程模式-举例讲解Python设计模式编程中的访问者与观察者模式

    访问者模式我觉得Visitor模式是在补修改已有程序结构前提下,通过添加额外的访问者完成对代码功能的拓展 为什么这样用?当你的类层次较多,在某层结构中增加新的方法,要是在基类上面添加或者变更,可能破坏 ...

  9. Java设计模式(2 / 23):观察者模式

    定义 观察者(Observer)模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新. OO设计原则:为了交互对象之间的松耦合设计而努力. 案例:气象监 ...

  10. 设计模式学习笔记之二:观察者模式

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

最新文章

  1. vue+file-saver+xlsx导出table为excel
  2. linux下批量添加新用户
  3. 151. 翻转字符串里的单词
  4. matlab 凹盘,刹车盘凹槽是怎么形成的
  5. 【学术相关】考研初试成绩出来了,然后呢...选导师!
  6. Jmeter----5.1 设置中文
  7. linux-facl权限控制-移除-复制
  8. nc和telnet配合使用
  9. 进程/线程间通信和同步
  10. 友图自动排料软件使用简介
  11. 数据库系统概论(各章知识点总结)
  12. HTTP请求的完全过程
  13. oracle数据库快速查询关键字,数据库分页查询关键字
  14. 解决局域网文件共享“****无法复制,指定的网络名不可用”
  15. python写word报告_使用Python自动生成word巡检报告【二】
  16. 恒辉信达全数据AI管控云平台动态运维管控
  17. 牛客网练习,某公司2017秋招。叫车 2017年
  18. mcgscom口针脚定义_标准9针串口引脚定义
  19. 不给电脑,我用手机敲命令十分钟完成了zabbix监控,面试官当场下offer
  20. 当代年轻人熬夜晚睡的原因找到了!

热门文章

  1. VB mschart控件的使用
  2. PDF文件打开密码解密
  3. win7卡在正在启动windows界面_电脑在“windows正在启动” 画面停留的时间长如何办...
  4. 【重点】commons-dbutils
  5. StringUtil工具类 之 字符串长度截取函数
  6. wincc新手之路-安装与授权
  7. 精锐万能票据打印专家
  8. VC++运行库安装难题
  9. Java回调函数实现案例
  10. 在VS中安装nuget离线包nupkg文件