观察者模式

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。观察者依赖于此主题,只要主题状态一有变化,观察者就会被通知,根据通知的风格,观察者可能因此新值而更新。关于观察者的一切,主题只知道观察者实现了某个接口,主题不需要知道观察者的具体类是谁、做了些什么工作或其他任何细节。任何时候我们都可以增加新的观察者,因为主题唯一依赖的东西是一个实现Observer接口的对象列表,所以我们可以随时增加观察者。假如我们有个新的具体类需要当观察者,不需要为了兼容新类型而修改主题代码,所有要做的就是在新的类里实现此观察者接口,然后注册为观察者即可。主题不在乎别的,它只发送通知给所有实现了观察者接口的对象。
 
#include"subject.h"

int main()
{
	WeatherData *weatherData = new WeatherData();
	CurrentConditionDisplay *currentDisplay = new CurrentConditionDisplay(weatherData);
	StatisticsDisplay *statisticsDisplay = new StatisticsDisplay(weatherData);
	ForecastDisplay *forecastDisplay = new ForecastDisplay(weatherData);
	weatherData->setMeasurements(80, 65, 30.4);
	weatherData->setMeasurements(82, 70, 29.2);
	weatherData->setMeasurements(78, 90, 29.2);
	delete weatherData;
	delete currentDisplay;
	delete statisticsDisplay;
	delete forecastDisplay;
}
#ifndef __SUBJECT_H
#define __SUBJECT_H
#include<vector>
#include<iostream>
using namespace std;

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

class Subject
{
public:
	virtual void registerObserver(Observer *O) = 0;
	virtual void removeObserver(Observer *O) = 0;
	virtual void notifyObservers() = 0;
};

class WeatherData :public Subject
{
private:
	vector<Observer*> observers;
	float temperature;
	float humidity;
	float pressure;
public:
	WeatherData(){}
	void registerObserver(Observer *o)
	{
		observers.push_back(o);
	}
	void removeObserver(Observer *o)
	{
		
	}
	void notifyObservers()
	{
		for (int i = 0; i < observers.size(); ++i)
		{
			observers[i]->update(temperature, humidity, pressure);
		}
	}
	void measurementsChanged()
	{
		notifyObservers();
	}
	void setMeasurements(float temperature, float humidity, float pressure)
	{
		this->temperature = temperature;
		this->humidity = humidity;
		this->pressure = pressure;
		measurementsChanged();
	}
};

class CurrentConditionDisplay :public Observer
{
private:
	float temperature;
	float humidity;
	Subject *weatherData;
public:
	CurrentConditionDisplay(Subject* weatherData) :weatherData(weatherData)
	{
		weatherData->registerObserver(this);
	}
	void update(float temperature, float humidity, float pressure)
	{
		this->temperature = temperature;
		this->humidity = humidity;
		display();
	}
	void display()
	{
		cout << "Current conditions: " << temperature << "F degrees and " << humidity << "% humidity" << endl;
	}
};

class StatisticsDisplay :public Observer
{
private:
	float maxTemp;
	float minTemp;
	float tempSum;
	int numReadings;
	Subject *weatherData;
public:
	StatisticsDisplay(Subject *weatherData) :weatherData(weatherData), maxTemp(0.0), minTemp(200.0), tempSum(0.0)
	{
		weatherData->registerObserver(this);
	}
	void update(float temp, float humidity, float pressure)
	{
		tempSum += temp;
		numReadings++;
		if (temp > maxTemp)
		{
			maxTemp = temp;
		}
		if (temp < minTemp)
		{
			minTemp = temp;
		}
		display();
	}
	void display()
	{
		cout << "Avg/Max/Min temperature = " << (tempSum / numReadings) << "/" << maxTemp << "/" << minTemp << endl;
	}
};

class ForecastDisplay :public Observer
{
private:
	float currentPressure;
	float lastPressure;
	Subject *weatherData;
public:
	ForecastDisplay(Subject *weather) :weatherData(weather), currentPressure(29.92), lastPressure(0.0)
	{
		weatherData->registerObserver(this);
	}
	void update(float temp, float humidity, float pressure)
	{
		lastPressure = currentPressure;
		currentPressure = pressure;
		display();
	}
	void display()
	{
		cout << "Forecast: ";
		if (currentPressure > lastPressure)
			cout << "Improving weather on the way" << endl;
		else if (currentPressure == lastPressure)
			cout << "More of the same" << endl;
		else
			cout << "Watch out for cooler, rainy weather" << endl;
	}
};
#endif

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值