观察者模式(Observer Pattern)

观察者模式(Observer Pattern):定义了对象之间的一对多依赖,这样一样,当一个对象(主题)改变状态时,它的所有依赖者(观察者)都会收到通知并自动更新

注:可以使用推或拉的方法,推(主题自动更新数据),拉(观察者主动更新数据,例如使用getter方法)

 

实例:气象站要实时通知布告板更新数据,布告板应该能灵活地增加

分析:如果在气象站里直接接加布告板则违反了针对接口编程的原则,无法动态地增加布告板.

 

代码:

JAVA:

  1. import java.util.ArrayList;
  2. interface Observer
  3. {
  4.     public void update(float temp, float humidity, float pressure);
  5. }
  6. interface Subject
  7. {
  8.     public void registerObserver(Observer o);
  9.     public void removeObserver(Observer o);
  10.     public void notifyObservers();
  11. }
  12. interface DisplayElement
  13. {
  14.     public void display();
  15. }
  16. class WeatherData implements Subject
  17. {
  18.     private ArrayList observers;
  19.     private float temperature;
  20.     private float humidity;
  21.     private float pressure;
  22.     public WeatherData()
  23.     {
  24.         observers = new ArrayList();
  25.     }
  26.     public void registerObserver(Observer o)
  27.     {
  28.         observers.add(o);
  29.     }
  30.     public void removeObserver(Observer o)
  31.     {
  32.         int i = observers.indexOf(o);
  33.         if (i >= 0)
  34.         {
  35.             observers.remove(i);
  36.         }
  37.     }
  38.     public void notifyObservers()
  39.     {
  40.         for (int i = 0; i < observers.size(); i++)
  41.         {
  42.             Observer observer = (Observer)observers.get(i);
  43.             observer.update(temperature, humidity, pressure);
  44.         }
  45.     }
  46.     public void measurementsChanged()
  47.     {
  48.         notifyObservers();
  49.     }
  50.     public void setMeasurements(float temperature, float humidity, float pressure)
  51.     {
  52.         this.temperature = temperature;
  53.         this.humidity = humidity;
  54.         this.pressure = pressure;
  55.         measurementsChanged();
  56.     }
  57. }
  58. class CurrentConditionsDisplay implements Observer, DisplayElement
  59. {
  60.     private float temperature;
  61.     private float humidity;
  62.     private Subject weatherData;
  63.     public CurrentConditionsDisplay(Subject weatherData)
  64.     {
  65.         this.weatherData = weatherData;
  66.         weatherData.registerObserver(this);
  67.     }
  68.     public void update(float temperature, float humidity, float pressure)
  69.     {
  70.         this.temperature = temperature;
  71.         this.humidity = humidity;
  72.         display();
  73.     }
  74.     public void display()
  75.     {
  76.         System.out.println("Current condition :" + temperature + "F degrees and " + humidity + "% humidity");
  77.     }
  78. }
  79. class ForecastDisplay implements Observer, DisplayElement
  80. {
  81.     private float currentPressure = 29.92f;
  82.     private float lastPressure;
  83.     private Subject weatherData;
  84.     public ForecastDisplay(Subject weatherData)
  85.     {
  86.         this.weatherData = weatherData;
  87.         weatherData.registerObserver(this);
  88.     }
  89.     public void update(float temperature, float humidity, float pressure)
  90.     {
  91.         
  92.             
  93.             lastPressure = currentPressure;
  94.             currentPressure = temperature;
  95.             display();
  96.         
  97.     }
  98.     public void display()
  99.     {
  100.         System.out.print("Forecast: ");
  101.         if (currentPressure > lastPressure)
  102.         {
  103.             System.out.println("Improving weather on the way!");
  104.         }
  105.         else if (currentPressure == lastPressure)
  106.         {
  107.             System.out.println("More of the same");
  108.         }
  109.         else if (currentPressure < lastPressure)
  110.         {
  111.             System.out.println("Watch out for cooler, rainy weather");
  112.         }
  113.     }
  114. }
  115. class StatisticsDisplay implements Observer, DisplayElement
  116. {
  117.     private float maxTemp = 0.0f;
  118.     private float minTemp = 200;
  119.     private float tempSum = 0.0f;
  120.     private int numReadings;
  121.      private Subject weatherData;
  122.      public StatisticsDisplay(Subject weatherData)
  123.     {
  124.         this.weatherData = weatherData;
  125.         weatherData.registerObserver(this);
  126.     }
  127.      public void update(float temperature, float humidity, float pressure)
  128.     {
  129.         
  130.             tempSum += temperature;
  131.             numReadings++;
  132.             if (temperature > maxTemp)
  133.             {
  134.                 maxTemp = temperature;
  135.             }
  136.             if (temperature < minTemp)
  137.             {
  138.                 minTemp = temperature;
  139.             }
  140.             display();
  141.         
  142.     }
  143.     public void display()
  144.     {
  145.         System.out.println("Avg/Max/Min temperature = " + (tempSum / numReadings)
  146.             + "/" + maxTemp + "/" + minTemp);
  147.     }
  148. }
  149. public  class WeatherStation
  150. {
  151.     public static void main(String[] args)
  152.     {
  153.         WeatherData weatherData = new WeatherData();
  154.         Observer currentDisplay = new CurrentConditionsDisplay(weatherData);
  155.         Observer forecastDisplay = new ForecastDisplay(weatherData);
  156.         Observer statisticsDisplay = new StatisticsDisplay(weatherData);
  157.         weatherData.setMeasurements(806530.4f);
  158.         weatherData.setMeasurements(827029.2f);
  159.         weatherData.removeObserver(forecastDisplay);
  160.         weatherData.setMeasurements(789029.2f);
  161.     }
  162. }

 

C++:

  1. // WeatherStation.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <iostream>
  5. #include <list>
  6. using namespace std;
  7. class Observer
  8. {
  9. public:
  10.     virtual  void update(float temp, float humidity, float pressure)=0;
  11. };
  12. class Subject
  13. {
  14. public:
  15.     virtual void registerObserver(Observer* o)=0;
  16.     virtual void removeObserver(Observer* o)=0;
  17.     virtual void notifyObservers()=0;
  18. };
  19. class DisplayElement
  20. {
  21. public:
  22.     virtual void display()=0;
  23. };
  24. class WeatherData :public  Subject
  25. {
  26. private
  27.     list<Observer *> observers;
  28.     float temperature;
  29.     float humidity;
  30.     float pressure;
  31. public:
  32.     WeatherData()
  33.     {
  34.         
  35.     }
  36.     void registerObserver(Observer* o)
  37.     {
  38.         observers.push_back(o);
  39.     }
  40.     void removeObserver(Observer* o)
  41.     {
  42.         observers.remove(o);
  43.         
  44.         
  45.     }
  46.     void notifyObservers()
  47.     {
  48.         list<Observer *>::iterator iter; 
  49.         for(iter=observers.begin();iter!=observers.end();iter++) 
  50.         { 
  51.             (*iter)->update(temperature, humidity, pressure);
  52.         } 
  53.     
  54.     }
  55.     void measurementsChanged()
  56.     {
  57.         notifyObservers();
  58.     }
  59.     void setMeasurements(float temperature, float humidity, float pressure)
  60.     {
  61.         this->temperature = temperature;
  62.         this->humidity = humidity;
  63.         this->pressure = pressure;
  64.         measurementsChanged();
  65.     }
  66. };
  67. class CurrentConditionsDisplay :public  Observer, public DisplayElement
  68. {
  69. private:
  70.     float temperature;
  71.     float humidity;
  72.     Subject* weatherData;
  73. public:
  74.     CurrentConditionsDisplay(Subject* weatherData)
  75.     {
  76.         this->weatherData = weatherData;
  77.         weatherData->registerObserver(this);
  78.     }
  79.     void update(float temperature, float humidity, float pressure)
  80.     {
  81.         this->temperature = temperature;
  82.         this->humidity = humidity;
  83.         display();
  84.     }
  85.     void display()
  86.     {
  87.         cout<<"Current condition :" << temperature << "F degrees and " << humidity << "% humidity/n";
  88.     }
  89. };
  90. class ForecastDisplay :public  Observer, public DisplayElement
  91. {
  92. private:
  93.     float currentPressure;
  94.     float lastPressure;
  95.     Subject* weatherData;
  96. public:
  97.     ForecastDisplay(Subject* weatherData)
  98.     {
  99.          currentPressure = 29.92f;
  100.         this->weatherData = weatherData;
  101.         weatherData->registerObserver(this);
  102.     }
  103.      void update(float temperature, float humidity, float pressure)
  104.     {
  105.         
  106.             
  107.             lastPressure = currentPressure;
  108.             currentPressure = temperature;
  109.             display();
  110.         
  111.     }
  112.      void display()
  113.     {
  114.         cout<<"Forecast: ";
  115.         if (currentPressure > lastPressure)
  116.         {
  117.             cout<<"Improving weather on the way!/n";
  118.         }
  119.         else if (currentPressure == lastPressure)
  120.         {
  121.             cout<<"More of the same/n";
  122.         }
  123.         else if (currentPressure < lastPressure)
  124.         {
  125.             cout<<"Watch out for cooler, rainy weather/n";
  126.         }
  127.     }
  128. };
  129. class StatisticsDisplay:public  Observer, public DisplayElement
  130. {
  131. private:
  132.     float maxTemp ;
  133.     float minTemp ;
  134.     float tempSum ;
  135.     int numReadings;
  136.      Subject* weatherData;
  137. public:
  138.     StatisticsDisplay(Subject* weatherData)
  139.     {
  140.         maxTemp = 0.0f;
  141.         minTemp = 200;
  142.         tempSum = 0.0f;
  143.         this->weatherData = weatherData;
  144.         weatherData->registerObserver(this);
  145.     }
  146.     void update(float temperature, float humidity, float pressure)
  147.     {
  148.         
  149.             tempSum += temperature;
  150.             numReadings++;
  151.             if (temperature > maxTemp)
  152.             {
  153.                 maxTemp = temperature;
  154.             }
  155.             if (temperature < minTemp)
  156.             {
  157.                 minTemp = temperature;
  158.             }
  159.             display();
  160.         
  161.     }
  162.     void display()
  163.     {
  164.         cout<<"Avg/Max/Min temperature = " << tempSum / numReadings<<"/" <<maxTemp << "/" << minTemp<<endl;
  165.     }
  166. };
  167. int _tmain(int argc, _TCHAR* argv[])
  168. {
  169.     WeatherData* weatherData = new WeatherData();
  170.     Observer* currentDisplay = new CurrentConditionsDisplay(weatherData);
  171.     Observer* forecastDisplay = new ForecastDisplay(weatherData);
  172.     Observer* statisticsDisplay =new StatisticsDisplay(weatherData);
  173.     weatherData->setMeasurements(80, 65, 30.4f);
  174.     weatherData->setMeasurements(82, 70, 29.2f);
  175.     weatherData->removeObserver(forecastDisplay);
  176.     weatherData->setMeasurements(78, 90, 29.2f);
  177.     return 0;
  178. }

 

结果:

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值