zoukankan      html  css  js  c++  java
  • Observer 观察者模式

    项目:气象监测系统

    需求分析::此系统中三个部分是气象站(获取实际气象数据的物理装置)、WeatherData对象(追踪气象站的数据,并更新布告板)和布告板(显示目前天气状况给用户看)。

    WeatherData对象知道如何跟物理气象站联系,以取得更新的数据。WeatherData对象会随机更新三个布告板的显示:目前状况(温度、湿度、气压)、气象统计和天气预报。

    当WeatherData对象发生变化时,即刻更新数据并推送给三个布告板。因此WeatherData需要获得布告板的引用,在数据更新时发送给布告板。用代码说话:

    首先设计2个接口:

    1. Subject,包含3个方法:Register, Remove, NotifyObservers

    2.Observer, 包含1个方法:Update

    设计WeatherData,实现Subject。除此之外还需要获得布告板引用,添加字段observerList集合,以及温度、湿度、气压字段。还有设置天气属性的的方法SetMeasurements,

    MeasurementsChanged方法,当设置天气属性时即调用改方法,然后通知注册的用户。

    1 namespace ObserverPattern
    2 {
    3     public  interface Subject
    4     {
    5         void RegisterObserver(Observer o);
    6         void RemoveObserver(Observer o);
    7         void NotifyObservers();
    8     }
    9 }
    1 namespace ObserverPattern
    2 {
    3     public interface Observer
    4     {
    5         void Update(float temp, float humidity, float pressure);
    6     }
    7 }
     1 using System.Collections.Generic;
     2 
     3 namespace ObserverPattern
     4 {
     5     public class WeatherData : Subject
     6     {
     7         private List<Observer> observerList = new List<Observer>();
     8         private float temperature;
     9         private float humidity;
    10         private float pressure;
    11 
    12         public void NotifyObservers()
    13         {
    14             foreach (Observer o in observerList)
    15             {
    16                 o.Update(temperature, humidity, pressure);
    17             }
    18         }
    19 
    20         public void RegisterObserver(Observer o)
    21         {
    22             observerList.Add(o);
    23         }
    24 
    25         public void RemoveObserver(Observer o)
    26         {
    27             if(observerList.Contains(o))
    28             {
    29                 observerList.Remove(o);
    30             }
    31           
    32         }
    33         /// <summary>
    34         /// 设置温度、湿度、气压
    35         /// </summary>
    36         /// <param name="temperature">温度</param>
    37         /// <param name="humidity">湿度</param>
    38         /// <param name="pressure">气压</param>
    39         public void SetMeasurements(float temperature, float humidity, float pressure)
    40         {
    41             this.temperature = temperature;
    42             this.humidity = humidity;
    43             this.pressure = pressure;
    44             MeasurementsChanged();
    45         }
    46         private void MeasurementsChanged( )
    47         {
    48             NotifyObservers();
    49         }
    50     }
    51 }

    接下来时设计3个布告板类,直接上代码:

     1 using System;
     2 
     3 namespace ObserverPattern
     4 {
     5     /// <summary>
     6     /// 此布告板根据WeatherData对象显示当前观测值
     7     /// </summary>
     8     public class CurrentConditionsDisplay : Observer, DisplayElement
     9     {
    10         private float temperature;
    11         private float humidity;
    12       
    13         private Subject weatherData;
    14 
    15         public CurrentConditionsDisplay()
    16         {
    17 
    18         }
    19         public CurrentConditionsDisplay(Subject w)
    20         {
    21             weatherData = w;
    22             weatherData.RegisterObserver(this);
    23         }
    24         /// <summary>
    25         /// 把最近的温度和湿度显示出来
    26         /// </summary>
    27         public void Display()
    28         {
    29             Console.WriteLine("Current conditions:{0} F degress and {1} % humidity", temperature, humidity);
    30         }
    31 
    32      
    33         public void Update(float temp, float humidity, float pressure)
    34         {
    35             this.temperature = temp;
    36             this.humidity = humidity;
    37             Display();
    38         }
    39     }
    40 }
     1 using System;
     2 
     3 namespace ObserverPattern
     4 {
     5     /// <summary>
     6     /// 此布告板根据气压计显示天气预报
     7     /// </summary>
     8     public class ForecastDisplay : Observer, DisplayElement
     9     {
    10         private WeatherData weatherData;
    11         private float currentPressure = 29.92f;
    12         private float lastPressure;
    13         public ForecastDisplay()
    14         {
    15 
    16         }
    17         public ForecastDisplay(WeatherData w)
    18         {
    19             weatherData = w;
    20             w.RegisterObserver(this);
    21         }
    22         public void Display()
    23         {
    24             Console.Write("Forecast: ");
    25             if(currentPressure > lastPressure)
    26             {
    27                 Console.WriteLine("天气状况转良!");
    28             }
    29             else if(currentPressure == lastPressure)
    30             {
    31                 Console.WriteLine("气压没有变化");
    32             }
    33             else
    34             {
    35                 Console.WriteLine("注意天气变凉,雨水天气");
    36             }
    37         }
    38 
    39       
    40 
    41         public void Update(float temp, float humidity, float pressure)
    42         {
    43             lastPressure = currentPressure;
    44             currentPressure = pressure;
    45             Display();
    46         }
    47     }
    48 }
     1 using System;
     2 
     3 namespace ObserverPattern
     4 {
     5     /// <summary>
     6     /// 此布告板跟踪最小、平均、最大的观测值,并显示它们
     7     /// </summary>
     8     public class StatisticsDisplay : Observer, DisplayElement
     9     {
    10         private WeatherData weatherData;
    11         private float maxTemp = 0f;
    12         private float minTemp = 200f;
    13         private float tempSum = 0f;
    14         private static int numReadings = 0;
    15         public StatisticsDisplay(WeatherData w)
    16         {
    17             weatherData = w;
    18             weatherData.RegisterObserver(this);
    19         }
    20         public StatisticsDisplay()
    21         {
    22                 
    23         }
    24         public void Display()
    25         {
    26             Console.WriteLine("Avg/Max/Min temperature = " + (tempSum / numReadings)
    27             + "/" + maxTemp + "/" + minTemp);
    28         }
    29 
    30        
    31 
    32         public void Update(float temp, float humidity, float pressure)
    33         {
    34             tempSum += temp;
    35             numReadings++;
    36             if(temp > maxTemp)
    37             {
    38                 maxTemp = temp;
    39             }
    40             if(temp < minTemp)
    41             {
    42                 minTemp = temp;
    43             }
    44             Display();
    45         }
    46     }
    47 }

                                         

     1 using System;
     2 
     3 namespace ObserverPattern
     4 {
     5     class WeatherStation
     6     {
     7         static void Main(string[] args)
     8         {
     9             WeatherData weatherData = new WeatherData();
    10             CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
    11             ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData);
    12             StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
    13             //模拟气象测量
    14             weatherData.SetMeasurements(80f, 65f, 30.4f);
    15             weatherData.SetMeasurements(100f, 62f, 28.0f);
    16             weatherData.SetMeasurements(86f, 72f, 26.3f);
    17             Console.ReadKey();
    18         }
    19     }
    20 }

    运行结果:

  • 相关阅读:
    lamp----6 实现虚拟主机ssl安全
    lamp-----5 apache虚拟主机实现,发布多个独立站点
    lamp----4 虚拟目录
    lamp----3 访问控制
    Apache配置反向代理、负载均衡和集群(mod_proxy方式)
    lamp-------3 userdir发布用户站点
    lamp------2 发布站点
    [转]KDE/QT与GNOME/GTK比较
    为什么会有文字聊天
    [转]gdb结合coredump定位崩溃进程
  • 原文地址:https://www.cnblogs.com/blackteeth/p/10207265.html
Copyright © 2011-2022 走看看