您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關怎么在c#項目中實現一個觀察者模式,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
1、觀察者模式UML圖
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.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#項目中實現一個觀察者模式就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。