`
kmplayer
  • 浏览: 510047 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Observer模式

阅读更多

1,核心:
很多个观察者关注一个object.
因此这些个observer注册同一个object.
object的变化调用NotifyAll,引起每个observer调用自己的update.

2,先给出一个实例:
#include <iostream>
#include <list>
#include <cassert>
using namespace std;

class Observer;
class Subject
{
protected:
    virtual ~Subject() = 0;
public:
    //注册观察者
    virtual void registerObserver( Observer* o ) = 0;
    //移除
	virtual void removeObserver( Observer* o ) = 0;
	//通知
	virtual void notifyObservers() const = 0;
};
Subject::~Subject() {}

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

class Observer //观察者基类
{
protected:
    virtual ~Observer() = 0 ;
public:
    //观察者得到通知,进行改变.
    virtual void update(float temp, float humidity, float pressure) = 0;
};
Observer::~Observer() {}

/*********************object*************************/
class WeatherData : public Subject
{
public:
    WeatherData() : _temperature( 0.0 ), _humidity( 0.0 ), _pressure( 0.0 )
    {}
    void registerObserver( Observer* o )
    {
        assert( o );
		_observers.push_back(o);
	}
	void removeObserver( Observer* o )
	{
	    assert( o );
		_observers.remove(o);
	}
	void notifyObservers() const
	{
		for( list< Observer* >::iterator iterator = _observers.begin(); _observers.end() != iterator; ++iterator )
		{
			(*iterator) -> update( _temperature, _humidity, _pressure );
		}
	}
	void measurementsChanged()
	{
		notifyObservers();
	}
	void setMeasurements( float temperature, float humidity, float pressure )
	{
		_temperature = temperature;
		_humidity = humidity;
		_pressure = pressure;
		measurementsChanged();
	}

	// other WeatherData methods here

	float getTemperature() const
	{
		return _temperature;
	}
	float getHumidity() const
	{
		return _humidity;
	}
	float getPressure() const
	{
		return _pressure;
	}

private:
	WeatherData( const WeatherData& ); // Disable copy constructor
	void operator=( const WeatherData& ); // Disable assignment operator

private:
    mutable list< Observer* > _observers;
	float _temperature;
	float _humidity;
	float _pressure;
};

/*********************observer*************************/
class CurrentConditionsDisplay : private Observer, private DisplayElement  //观察者1
{
public:
    explicit CurrentConditionsDisplay( Subject* weatherData ) :
		_weatherData( weatherData ), _temperature( 0.0 ), _humidity( 0.0 )
    {
        assert( weatherData );
		_weatherData -> registerObserver( this ); //构造,注册
	}
    ~CurrentConditionsDisplay()
    {
		_weatherData->removeObserver( this ); //析构 移除
	}
	void update( float temperature, float humidity, float pressure )
	{
		_temperature = temperature;
		_humidity = humidity;
		display();
	}
	void display() const
	{
		cout.setf( ios::showpoint );
		cout.precision(3);
		cout << "Current conditions: "	<< _temperature;
		cout << " F degrees and " << _humidity;
		cout << "% humidity" << endl;
	}
private:
    CurrentConditionsDisplay( const CurrentConditionsDisplay& ); // Disable copy constructor
	void operator=( const CurrentConditionsDisplay& ); // Disable assignment operator
private:
    Subject* _weatherData;
	float _temperature;
	float _humidity;
};

class ForecastDisplay : private Observer, private DisplayElement
{
public:
    explicit ForecastDisplay( WeatherData* weatherData ) :
		_weatherData( weatherData ), _currentPressure( 29.92F ), _lastPressure( 0 )
    {
        assert( weatherData );
		weatherData->registerObserver( this );
	}
	~ForecastDisplay()
	{
		_weatherData->removeObserver( this );
	}
	void update( float temp, float humidity, float pressure )
	{
        _lastPressure = _currentPressure;
		_currentPressure = pressure;
		display();
	}
	void display() const
	{
		cout.setf( ios::showpoint );
		cout.precision(3);
		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;
	}
private:
    ForecastDisplay( const ForecastDisplay& ); // Disable copy constructor
	void operator=( const ForecastDisplay& ); // Disable assignment operator
private:
    WeatherData* _weatherData;
	float _currentPressure;
	float _lastPressure;
};

class StatisticsDisplay : private Observer, private DisplayElement
{
public:
    explicit StatisticsDisplay( WeatherData* weatherData ) :
		_weatherData( weatherData ), _maxTemp( 0.0 ), _minTemp( 200.0F ), _tempSum( 0.0 ), _numReadings( 0 )
    {
        assert( weatherData );
		_weatherData->registerObserver( this );
	}
	~StatisticsDisplay()
	{
		_weatherData->removeObserver( this );
	}
	void update( float temp, float humidity, float pressure )
	{
		_tempSum += temp;
		_numReadings++;
		if( temp > _maxTemp )
		{
			_maxTemp = temp;
		}
		if( temp < _minTemp )
		{
			_minTemp = temp;
		}
		display();
	}
	public: void display() const
	{
		cout.setf( ios::showpoint );
		cout.precision(3);
		cout << "Avg/Max/Min temperature = " << ( _tempSum / _numReadings );
		cout << "/" << _maxTemp << "/" << _minTemp << endl;
	}
private:
    StatisticsDisplay( const StatisticsDisplay& ); // Disable copy constructor
	void operator=( const StatisticsDisplay& ); // Disable assignment operator
private:
	WeatherData* _weatherData;
	float _maxTemp;
	float _minTemp;
	float _tempSum;
	int _numReadings;
};

class HeatIndexDisplay : private Observer, private DisplayElement
{
public:
    explicit HeatIndexDisplay( Subject* weatherData ) :
		_weatherData( weatherData ), _heatIndex( 0.0 )
    {
        assert( weatherData );
		_weatherData->registerObserver( this );
	}
	~HeatIndexDisplay()
	{
		_weatherData->removeObserver( this );
	}
	void update( float t, float rh, float pressure )
	{
		_heatIndex = computeHeatIndex( t, rh );
		display();
	}
	float computeHeatIndex( float t, float rh ) const
	{
		float index = (float)((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;
	}
	void display() const
	{
		cout.setf( ios::showpoint);
		cout.precision(7);
		cout << "Heat index is " << _heatIndex << endl;
	}
private:
    HeatIndexDisplay( const HeatIndexDisplay& ); // Disable copy constructor
	void operator=( const HeatIndexDisplay& ); // Disable assignment operator
private:
    Subject* _weatherData;
	float _heatIndex;
};

int main()
{
    WeatherData weatherData;
	CurrentConditionsDisplay currentDisplay( &weatherData );
	StatisticsDisplay statisticsDisplay( &weatherData );
    ForecastDisplay forecastDisplay( &weatherData );
    HeatIndexDisplay heatIndexDisplay( &weatherData );

    weatherData.setMeasurements( 80, 65, 30.4f );
	weatherData.setMeasurements( 82, 70, 29.2f );
	weatherData.setMeasurements( 78, 90, 29.2f );
    return 0;
}
分享到:
评论

相关推荐

    Observer模式的传统实现和AOP实现

    对Observer模式的实现,引入后可直接使用。 包括传统实现和遵循AOP思想的实现

    重温Observer模式--热水器·改

    Observer模式是一种设计模式,主要目的是实现对象之间的松耦合,使得当一个对象的状态发生改变时,依赖于这个对象状态的其他对象能够得到通知并自动更新。在这个“重温Observer模式--热水器·改”的讨论中,作者将...

    observer模式实现示例

    Observer模式是一种设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。在C++编程中,Observer模式通常通过函数指针或者接口来实现,这两种方法...

    OBserver模式设计实现

    标题中的"OBserver模式设计实现"是指探讨如何在实际编程中应用观察者模式,无论是用Java还是C++。Head First系列书籍是著名的编程学习资源,以易懂的方式解释复杂的设计模式。在描述中提到的"Head First模式设计用的...

    Observer模式代码实现

    ### Observer模式代码实现 #### 观察者模式简介 观察者模式(Observer Pattern)是一种行为设计模式,它定义了对象间的一种一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动...

    Observer模式的应用

    请选用适当的设计模式,编写一个股票行情分析软件,随着时间的推移和股票价格的变动,实现各种指标的动态更新(要求至少实现一个股票的分时图和K线图:为降低编程工作量,K线图可以用开盘价、收盘价、最高价、最低价...

    Observer 模式

    Observer模式是一种行为设计模式,它允许你定义一个订阅机制,可以在对象状态改变时通知多个“观察者”对象,使得它们能够自动更新自己。这个模式在软件工程中扮演着重要的角色,尤其是在事件驱动或数据绑定的系统中...

    Android学习 ContentProvider数据更新与Observer模式.doc

    在Android开发中,ContentProvider和Observer模式是两个关键的概念,它们在数据管理和更新中起着重要作用。ContentProvider作为Android系统中数据共享的桥梁,允许不同的应用程序之间交换数据,而Observer模式则是一...

    C++ Observer模式

    Observer模式,也称为“订阅”或“发布-订阅”模式,是软件设计中的一种行为模式,主要用于处理对象间的一对多依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这个模式在C++中...

    Observer设计模式实例

    在Observer模式中,主要有两个关键角色:Subject(主题)和Observer(观察者)。Subject维护了一个Observer的列表,并负责在状态变化时通知它们。Observer则关注Subject,当Subject状态变化时,Observer会收到通知并...

    observer 模式例子的源码(天气监测问题)

    这是老师上课讲observer模式的Java例子,容易看懂。 题目:基于我们拥有专利的气象数据对象来提供各种气象报告(气象数据对象收集当前的气象数据,包括温度、湿度和气压)。初期要求提供三类报告:当前天气情况、...

    Observer模式代码

    Observer模式,也称为“发布-订阅”模式,是软件设计模式中的行为模式之一。它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。Observer模式是解耦系统...

    Observer与Command模式在VTK类库设计中的应用研究

    Observer模式是一种行为设计模式,用于定义对象间的依赖关系,以便当一个对象(目标)的状态发生变化时,所有依赖于它的对象(观察者)都会自动收到通知并更新自身。这种模式能够帮助开发者创建灵活且可扩展的系统,...

    设计模式之Observer

    Observer模式,又称为“观察者模式”或“发布-订阅模式”,是一种行为设计模式,用于在对象之间建立一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。Observer模式...

    设计模式精解-GoF 23 种设计模式解析附 C++实现源码 单最常用的设计模式入门,比如AbstractFactory模式、Adapater模式、Composite模式、Decorator模式、Factory模式、Observer模式、Strategy模式、Template模式等

    设计模式体现的是一种思想,而思想则是指导行为的一切,理解和掌握了设计模式,并不是说记住了23种(或更多)设计场景和解决策略(实际上这也是很重要的一笔财富),实际接受的是一种思想的熏陶和洗礼,等这种思想...

    Java设计模式之观察者模式(Observer模式)介绍

    观察者模式(Observer模式)是软件设计模式中的一种行为模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。在Java中,这个模式是通过`java.util....

Global site tag (gtag.js) - Google Analytics