设计模式Observer

来源:互联网 发布:js控制浏览器最小化 编辑:程序博客网 时间:2024/03/29 02:20

Observer设计模式的定义:

    定义了对象之间的一对多的依赖,这样以来,当一个对象改变状态时,它的所有依赖者都会受到通知并自动更新。

********************************************

//Subject.h

********************************************

#ifndef SUBJEC_H
#define SUBJEC_H

#include"Observer.h"

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

Subject::Subject(){}
Subject::~Subject(){}

#endif

**********************************************

//WeatherData.h

**********************************************

#ifndef WEATHERDATA_H
#define WEATHERDATA_H

#include"Subject.h"
#include<list>
using namespace std;

class WeatherData:public Subject
{
   private:
        list<Observer*>observerList;
        float temperature;
        float humidity;
        float pressure;
   public:
        WeatherData();
        ~WeatherData();
        void registerObserver(Observer *o);
        void removeObserver(Observer *o);
        void notifyObservers();
        void measurementsChanged();
        void setMeasurements(float temperature,float humidity,float pressure);
};

WeatherData::WeatherData(){}
WeatherData::~WeatherData(){}

void WeatherData::registerObserver(Observer *o)
{
     observerList.push_back(o);
}

void WeatherData::removeObserver(Observer *o)
{
    observerList.remove(o);
}

void WeatherData::notifyObservers()
{
    for(list<Observer*>::iterator it=observerList.begin();it!=observerList.end();it++)
     {
        (*it)->update(temperature,humidity,pressure);
     }
}

void WeatherData::measurementsChanged()
{
     notifyObservers();
}

void WeatherData::setMeasurements(float temperature,float humidity,float pressure)
{
    this->temperature=temperature;
    this->humidity=humidity;
    this->pressure=pressure;
    measurementsChanged();
}

#endif

**********************************************

//DisplayElement.h

**********************************************

#ifndef DISPLAYELEMENT_H
#define DISPLAYELEMENT_H

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

DisplayElement::DisplayElement(){}
DisplayElement::~DisplayElement(){}

#endif

**********************************************

//Observer.h

**********************************************

#ifndef OBSERVER_H
#define OBSERVER_H

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

Observer::Observer(){}
Observer::~Observer(){}

#endif

**********************************************

//CurrentConditionsDisplay.h

**********************************************

#ifndef CURRENTCONDITIONSDISPLAY_H
#define CURRENTCONDITIONSDISPLAY_H

#include"Subject.h"
#include"Observer.h"
#include"DisplayElement.h"
#include<iostream>
using namespace std;

class CurrentConditionsDisplay:public Observer,public DisplayElement
{
   private:
          float temperature;
          float humidity;
          Subject *weatherData;
   public:
         CurrentConditionsDisplay(Subject *weatherData);
        ~CurrentConditionsDisplay();
         void update(float temperature,float humidity,float pressure);
         void display();
};

CurrentConditionsDisplay::CurrentConditionsDisplay(Subject *weatherData)
{
       this->weatherData=weatherData;
       weatherData->registerObserver(this);
}
CurrentConditionsDisplay::~CurrentConditionsDisplay(){}
void CurrentConditionsDisplay::update(float temperature,float humidity,float pressure)
{
      this->temperature=temperature;
      this->humidity=humidity;
     display();
}

void CurrentConditionsDisplay::display()
{
      cout<<"Current conditions:"<<temperature<<"F degrees and"<<humidity<<"%humidity"<<endl;
}

#endif

**********************************************

//StatisticsDisplay.h

**********************************************

#ifndef STATISTICSDISPLAY_H
#define STATISTICSDISPLAY_H

#include"Subject.h"
#include"Observer.h"
#include"DisplayElement.h"
#include<iostream>
using namespace std;

class StatisticsDisplay:public Observer,public DisplayElement
{
   private:
         float maxTemp;
         float minTemp;
         float tempSum;
         int numReadings;
         Subject *weatherData;
   public:
         StatisticsDisplay(Subject *weatherData);
        ~StatisticsDisplay();
         void update(float temperature,float humidity,float pressure);
         void display();
};

StatisticsDisplay::StatisticsDisplay(Subject *weatherData)
{
       maxTemp=0.0f;
       minTemp=200;
       tempSum=0;
       numReadings=0;
       this->weatherData=weatherData;
       weatherData->registerObserver(this);
}
StatisticsDisplay::~StatisticsDisplay(){}

void StatisticsDisplay::update(float temperature,float humidity,float pressure)
{
     tempSum+=temperature;
     numReadings++;
     if(temperature>maxTemp)
     maxTemp=temperature;
     if(temperature<minTemp)
     minTemp=temperature;
     display();
}

void StatisticsDisplay::display()
{
      cout<<"Avg/Max/Min temperature="<<tempSum/numReadings<<"/"<<maxTemp<<"/"<<minTemp<<endl;
}


#endif

**********************************************

//ForecastDisplay.h

**********************************************

#ifndef FORECASTDISPLAY_H
#define FORECASTDISPLAY_H

#include"Subject.h"
#include"Observer.h"
#include"DisplayElement.h"
#include<iostream>
using namespace std;

class ForecastDisplay:public Observer,public DisplayElement
{
   private:
          float currentPressure;  
          float lastPressure;
          Subject *weatherData;
   public:
          ForecastDisplay(Subject *weatherData);
          ~ForecastDisplay();
          void update(float temperature,float humidity,float pressure);
          void display();
};

ForecastDisplay::ForecastDisplay(Subject *weatherData)
{
      currentPressure=29.92f;
      this->weatherData=weatherData;
      weatherData->registerObserver(this);
}
ForecastDisplay::~ForecastDisplay(){}

void ForecastDisplay::update(float temperature,float humidity,float pressure)
{

     lastPressure = currentPressure;
     currentPressure = pressure;
     display();
}

void ForecastDisplay::display()
{
     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

**********************************************

//HeatIndexDisplay.h

**********************************************

#ifndef HEATINDEXDISPLAY_H
#define HEATINDEXDISPLAY_H

#include"Subject.h"
#include"Observer.h"
#include"DisplayElement.h"
#include<iostream>
using namespace std;

class HeatIndexDisplay:public Observer,public DisplayElement
{
   private:
          float heatIndex;
          Subject *weatherData;
   public:
          HeatIndexDisplay(Subject *weatherData);
        ~HeatIndexDisplay();
         void update(float temperature,float humidity,float pressure);
         void display();
         float computeHeatIndex(float t,float rh);
};

HeatIndexDisplay::HeatIndexDisplay(Subject *weatherData)
{
       heatIndex=0.0f;
       this->weatherData=weatherData;
       weatherData->registerObserver(this);
}
HeatIndexDisplay::~HeatIndexDisplay(){}

void HeatIndexDisplay::update(float temperature,float humidity,float pressure)
{
     heatIndex=computeHeatIndex(temperature,humidity);
     display();
}


float HeatIndexDisplay::computeHeatIndex(float t,float rh)
{
  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 HeatIndexDisplay::display()
{
    cout<<"Heat index is :"<<heatIndex<<endl;
}

#endif

**********************************************

//WeatherStation.cpp

**********************************************

#include"WeatherData.h"
#include"CurrentConditionsDisplay.h"
#include"StatisticsDisplay.h"
#include"ForecastDisplay.h"
#include"HeatIndexDisplay.h"


int main()
{
      WeatherData *weatherData=new WeatherData();
     CurrentConditionsDisplay *currentDisplay=new CurrentConditionsDisplay(weatherData);
     StatisticsDisplay *statisticsDisplay=new StatisticsDisplay(weatherData);
      ForecastDisplay *forecastDisplay=new ForecastDisplay(weatherData);
      HeatIndexDisplay *heatIndexDisplay=new HeatIndexDisplay(weatherData);
      weatherData->setMeasurements(80,65,30.4);
      weatherData->setMeasurements(82,70,29.2);
      weatherData->setMeasurements(78,90,29.2);
      return 0;
}

**********************************************

原创粉丝点击