C# IObservable与IObserver观察者模式

  • A+
所属分类:.NET技术
摘要

C#中提供了IObservable<T>接口和IObserver<T>接口来实现观察者模式,IObservable<T>相当于Subject(主题)接口,下面我们就以代吗来说明下如何利用.net框架提供的观察者模式接口。

C#中提供了IObservable<T>接口和IObserver<T>接口来实现观察者模式,IObservable<T>相当于Subject(主题)接口,下面我们就以代吗来说明下如何利用.net框架提供的观察者模式接口。

 

WeatherData类包含气温,湿度,气压等属性。

    class WeatherData     {         /// <summary>         /// 气温         /// </summary>         public string temperature { get; set; }         /// <summary>         /// 湿度         /// </summary>         public string humility { get; set; }         /// <summary>         /// 气压         /// </summary>         public string pressure { get; set; }     }

 

WeatherDataPublisher类实现了IObservable接口,实现了Subscribe订阅方法。

    class WeatherDataPublisher : IObservable<WeatherData>     {         List<IObserver<WeatherData>> observers = new List<IObserver<WeatherData>>();         /// <summary>         /// 订阅主题,将观察者添加到列表中         /// </summary>         /// <param name="observer"></param>         /// <returns></returns>         public IDisposable Subscribe(IObserver<WeatherData> observer)         {             observers.Add(observer);             return new Unsubscribe(this.observers, observer);         }         /// <summary>         /// 取消订阅类         /// </summary>         private class Unsubscribe : IDisposable         {             List<IObserver<WeatherData>> observers;             IObserver<WeatherData> observer;             public Unsubscribe(List<IObserver<WeatherData>> observers             , IObserver<WeatherData> observer)             {                 this.observer = observer;                 this.observers = observers;             }              public void Dispose()             {                 if (this.observers != null)                 {                     this.observers.Remove(observer);                 }             }         }         /// <summary>         /// 通知已订阅的观察者         /// </summary>         /// <param name="weatherData"></param>         private void Notify(WeatherData weatherData)         {             foreach (var observer in observers)             {                 observer.OnNext(weatherData);             }         }         /// <summary>         /// 接收最新的天气数据         /// </summary>         /// <param name="weatherData"></param>         public void ReciveNewData(WeatherData weatherData)         {             Notify(weatherData);         }     }

 

下面我们建立一个抽象类WeatherDisplayBase实现了IObserver接口,所有的天气展示板(观察者)继承这个抽象类,需实现OnNext方法,即接收到新数据推送后要进行的数据处理展示工作,并且可重写OnCompleted,OnError方法。

    abstract class WeatherDisplayBase : IObserver<WeatherData>     {         public virtual void OnCompleted()         {         }         public virtual void OnError(Exception error)         {         }         public abstract void OnNext(WeatherData value);     }

 

CurrentConditionDisplay类为当前天气状况展示板,继承WeatherDisplayBase抽象类,展示最新的天气数据。

    class CurrentConditionDisplay : WeatherDisplayBase     {         public override void OnNext(WeatherData value)         {             Console.WriteLine("------------------");             Console.WriteLine("当前天气状况板");             Console.WriteLine(string.Format("温度:{0}n湿度:{1}n气压:{2}",                 value.temperature, value.humility, value.pressure));         }     }

 

StatisticsConditionDisplay类为气温统计展示板,继承WeatherDisplayBase抽象类,展示历史最高温度,最低温度,平均温度。

    class StatisticsConditionDisplay : WeatherDisplayBase     {         List<float> temperatures = new List<float>();         public override void OnNext(WeatherData value)         {             float temperature;             if (float.TryParse(value.temperature, out temperature))             {                 temperatures.Add(temperature);             }             Console.WriteLine("------------------");             Console.WriteLine("温度统计板");             Console.WriteLine(string.Format("平均温度:{0}n最高温度:{1}n最低温度:{2}",                 temperatures.Average(), temperatures.Max(), temperatures.Min()));         }     }

 

使用方法

class Program     {         static void Main(string[] args)         {             WeatherDataPublisher publisher = new WeatherDataPublisher();             CurrentConditionDisplay currentDisplay=new CurrentConditionDisplay();             StatisticsConditionDisplay statisticsDisplay              = new StatisticsConditionDisplay();             //订阅当前天气展示板             IDisposable currentDisplayUnsubscriber=              publisher.Subscribe(currentDisplay);             //订阅气温统计展示板             IDisposable statisticsDisplayUnsubscriber =              publisher.Subscribe(statisticsDisplay);                           for (int i = 0; ; i++)             {                 WeatherData weatherData = new WeatherData();                Console.WriteLine("请输入温度,湿度,压力");                string input = Console.ReadLine();                var array= input.Split(',');                weatherData.temperature = array[0];                weatherData.humility = array[1];                weatherData.pressure = array[2];                Console.WriteLine("");                 //将输入的新的天气数据传给天气数据发布器                publisher.ReciveNewData(weatherData);                Console.WriteLine("=============================");             }         } }