c# 实现观察者模式

时间:2021-05-20

说明:主要参考《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.2Subject

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.3IObservable具体实现

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# 观察者模式的资料请关注其它相关文章!

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章