c# 实现观察者模式

Abbie ·
更新时间:2024-11-14
· 515 次阅读

说明:主要参考《Head First设计模式(中文版)》,使用C#代码实现。

代码:Github

1、观察者模式UML图

2、气象监测类图

3、气象监测代码(书中C#版)

3.1 Observer

public interface IObserver {     void Update(float temperature, float humidity, float pressure); } public interface IDisplayElement {     void Display(); } public class CurrentConditionDisplay : IObserver, IDisplayElement {     private readonly ISubject _weatherData;       private float _temperature;     private float _humidity;       public CurrentConditionDisplay(ISubject weatherData)     {         _weatherData = weatherData;         _weatherData?.RegisterObserver(this);     }       public void Update(float temperature, float humidity, float pressure)     {         _temperature = temperature;         _humidity = humidity;         Display();     }       public void Display()     {         Console.WriteLine($"Current Conditions: {_temperature}F degress and {_humidity}% humidity");     } }

3.2 Subject

public interface ISubject {     void RegisterObserver(IObserver o);     void RemoveObserver(IObserver o);     void NotifyObservers(); } public class WeatherData : ISubject {     //观察者列表     private readonly List<IObserver> _observerList;       //天气数据     private float _temperature;     private float _humidity;     private float _pressure;       public WeatherData()     {         _observerList = new List<IObserver>();     }       /// <summary>     /// 订阅观察者     /// </summary>     /// <param name="o">观察者对象</param>     public void RegisterObserver(IObserver o)     {         _observerList.Add(o);     }       /// <summary>     /// 移除观察者     /// </summary>     /// <param name="o">观察者对象</param>     public void RemoveObserver(IObserver o)     {         if (_observerList.Contains(o))         {             _observerList.Remove(o);         }     }       /// <summary>     /// 发布数据     /// </summary>     public void NotifyObservers()     {         foreach (var observer in _observerList)         {             observer.Update(_temperature, _humidity, _pressure);         }     }       /// <summary>     /// 数据发生改变     /// </summary>     private void MeasurementChanged()     {         NotifyObservers();     }       /// <summary>     /// 更新数据     /// </summary>     /// <param name="temperature">温度</param>     /// <param name="humidity">湿度</param>     /// <param name="pressure">气压</param>     public void SetMeasurements(float temperature, float humidity, float pressure)     {         _temperature = temperature;         _humidity = humidity;         _pressure = pressure;         MeasurementChanged();     } }

3.3 测试代码

private static void TestWeatherData() {     var weatherData = new WeatherData();     var currentConditionDisplay = new CurrentConditionDisplay(weatherData);       weatherData.SetMeasurements(80, 65, 30.4f);     weatherData.SetMeasurements(82, 70, 29.2f);     weatherData.SetMeasurements(78, 90, 29.2f); } 4、使用C#中IObservable接口实现气象监测

4.1 辅助类/结构体

public struct WeatherMessage {     public float Temperature { get; set; }     public float Humidity { get; set; }     public float Pressure { get; set; } }   public class MessageUnknownException : Exception {     internal MessageUnknownException()     {       } }

4.2 IObserver具体实现

class CurrentConditionDisplayX : IObserver<WeatherMessage>, IDisplayElement {     private IDisposable _unsubscribe;       private float _temperature;     private float _humidity;       public void Subscribe(IObservable<WeatherMessage> provider)     {         if (provider != null)         {             _unsubscribe = provider.Subscribe(this);         }     }       public void Unsubscribe()     {         _unsubscribe?.Dispose();         _unsubscribe = null;     }       public void OnCompleted()     {         Console.WriteLine("CurrentConditionDisplayX: OnCompleted");         Unsubscribe();     }       public void OnError(Exception error)     {         Console.WriteLine("CurrentConditionDisplayX: OnError");     }       public void OnNext(WeatherMessage value)     {         _temperature = value.Temperature;         _humidity = value.Humidity;         Display();     }       public void Display()     {         Console.WriteLine($"Current Conditions: {_temperature}F degress and {_humidity}% humidity");     } }

4.3 IObservable具体实现

public class WeatherDataX : IObservable<WeatherMessage> {     private readonly List<IObserver<WeatherMessage>> _observerList;       public WeatherDataX()     {         _observerList = new List<IObserver<WeatherMessage>>();     }       /// <summary>     /// 通知提供程序:某观察程序将要接收通知。     /// </summary>     /// <param name="observer">要接收通知的对象。</param>     /// <returns>使资源释放的观察程序的接口。</returns>     public IDisposable Subscribe(IObserver<WeatherMessage> observer)     {         if(!_observerList.Contains(observer))         {             _observerList.Add(observer);         }         return new Unsubcriber(_observerList, observer);     }       public void SetMeasurements(Nullable<WeatherMessage> message)     {         foreach (var observer in _observerList)         {             if (!message.HasValue)             {                 observer.OnError(new MessageUnknownException());             }             else             {                 observer.OnNext(message.Value);             }         }     }       public void EndTransmission()     {         foreach (var observer in _observerList.ToArray())         {             if (_observerList.Contains(observer))             {                 observer.OnCompleted();             }         }         _observerList.Clear();     }       private class Unsubcriber : IDisposable     {         private List<IObserver<WeatherMessage>> _observerList;         private IObserver<WeatherMessage> _observer;           public Unsubcriber(List<IObserver<WeatherMessage>> observerList, IObserver<WeatherMessage> observer)         {             _observerList = observerList;             _observer = observer;         }           public void Dispose()         {             if (_observerList != null && _observerList.Contains(_observer))             {                 _observerList.Remove(_observer);             }         }     } }

4.4 测试代码

private static void TestWeatherDataX() {     var weatherData = new WeatherDataX();     var currentConditionDisplay = new CurrentConditionDisplayX();       currentConditionDisplay.Subscribe(weatherData);       weatherData.SetMeasurements(new WeatherMessage()     {         Temperature = 80,         Humidity = 65,         Pressure = 30.4f     });     weatherData.SetMeasurements(new WeatherMessage()     {         Temperature = 82,         Humidity = 70,         Pressure = 29.2f     });     weatherData.SetMeasurements(new WeatherMessage()     {         Temperature = 78,         Humidity = 90,         Pressure = 29.2f     });     weatherData.EndTransmission(); }

以上就是c# 实现观察者模式的详细内容,更多关于c# 观察者模式的资料请关注软件开发网其它相关文章!

您可能感兴趣的文章:C#设计模式之Observer观察者模式解决牛顿童鞋成绩问题示例C# 设计模式系列教程-观察者模式C#设计模式之观察者模式实例讲解c# 使用计时器和观察者模式实现报警推送需求C#中观察者模式的3种实现方式C#观察者模式(Observer Pattern)实例教程C#中委托和事件在观察者模式中的应用实例C# 观察者模式实例介绍



C# 观察者模式

需要 登录 后方可回复, 如果你还没有账号请 注册新账号