首页 > 编程 > C++ > 正文

《Head First 设计模式》例子的C++实现(2 观察者模式)

2019-11-08 02:39:13
字体:
来源:转载
供稿:网友

最近在学习设计模式,用的是 《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);}
上一篇:C++类中使用typedef

下一篇:C++问题汇总

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选