觀察者模式
觀察者模式定義了對象之間的一對多的依賴,這樣一來,當一個對象的狀態改變時,它的所有依賴者都會收到通知並且自動更新。
實現方法
觀察的對象爲可觀察者,要被通知的對象稱爲觀察者。
觀察者都實現同一個接口,裏面有一個方法用來被可觀察者調用,實現通知的功能。可觀察者實現可被觀察的接口,在觀察者中調用可觀察者接口的方法實現註冊,刪除觀察者等功能。
代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 觀察者模式
{
class Program
{
static void Main(string[] args)
{
WeatherData weatherData=new WeatherData();
CurrentConditionsDisplay currentDisplay=new CurrentConditionsDisplay(weatherData);
StatisticsDisplay statisticsDisplay=new StatisticsDisplay(weatherData);
ForecastDisplay forecastDisplay=new ForecastDisplay(weatherData);
// 虛擬數據
weatherData.SetMeasurements(80,65,30.4f);
weatherData.SetMeasurements(82, 70, 29.2f);
weatherData.SetMeasurements(78, 90, 29.2f);
Console.ReadKey();
}
}
// 觀察者接口
public interface IObserver
{
// 更新數據方法
void Update(float temp,float humidity,float pressure);
}
// 觀察者目標接口
public interface ISubject
{
// 註冊觀察者方法
void RegisterObserver(IObserver o);
// 移除觀察者方法
void RemoveObserver(IObserver o);
// 通知方法
void NotifyObservers();
}
// 顯示接口
public interface IDisplayElement
{
// 顯示方法
void Display();
}
// 觀察者的具體目標,實現目標接口
public class WeatherData:ISubject
{
private List<IObserver> _observers; // 觀察者列表
private float _temprature;
private float _humidity;
private float _pressure;
public WeatherData()
{
_observers=new List<IObserver>();
}
// 註冊觀察者
public void RegisterObserver(IObserver o)
{
_observers.Add(o);
}
// 移除觀察者
public void RemoveObserver(IObserver o)
{
if (_observers.Contains(o))
{
_observers.Remove(o);
}
}
// 通知觀察者值改變,通過調用觀察者列表中實現觀察者接口的函數
public void NotifyObservers()
{
foreach (var observer in _observers)
{
observer.Update(_temprature,_humidity,_pressure);
}
}
// 通知觀察者值發生改變
public void MeasurementsChanged()
{
NotifyObservers();
}
// 獲取實時值並且通知值改變
public void SetMeasurements(float temperature, float humidity, float pressure)
{
_temprature = temperature;
_humidity = humidity;
_pressure = pressure;
MeasurementsChanged();
}
// WeatherData 的其它方法
}
// 具體的觀察者
public class CurrentConditionsDisplay:IObserver,IDisplayElement
{
private float _temprature;
private float _humidity;
private ISubject _weatherData;
// 實例化時傳入觀察目標實例的接口
public CurrentConditionsDisplay(ISubject weatherData)
{
_weatherData = weatherData;
_weatherData.RegisterObserver(this);
}
// 通過接口方法獲得數據
public void Update(float temp, float humidity, float pressure)
{
_temprature = temp;
_humidity = humidity;
Display();
}
public void Display()
{
Console.WriteLine($"Current conditions: {_temprature}F degrees and {_humidity}% humidity");
}
}
public class ForecastDisplay : IObserver, IDisplayElement
{
private float _temprature;
private float _humidity;
private ISubject _weatherData;
public ForecastDisplay(ISubject weatherData)
{
_weatherData = weatherData;
_weatherData.RegisterObserver(this);
}
public void Update(float temp, float humidity, float pressure)
{
_temprature = temp;
_humidity = humidity;
Display();
}
public void Display()
{
Console.WriteLine($"Forecast: {_temprature}F degrees and {_humidity}% humidity");
}
}
public class ThirdPartyDisplay : IObserver, IDisplayElement
{
private float _temprature;
private float _humidity;
private ISubject _weatherData;
public ThirdPartyDisplay(ISubject weatherData)
{
_weatherData = weatherData;
_weatherData.RegisterObserver(this);
}
public void Update(float temp, float humidity, float pressure)
{
_temprature = temp;
_humidity = humidity;
Display();
}
public void Display()
{
Console.WriteLine($"ThirdParty: {_temprature}F degrees and {_humidity}% humidity");
}
}
public class StatisticsDisplay : IObserver, IDisplayElement
{
private float _temprature;
private float _humidity;
private ISubject _weatherData;
public StatisticsDisplay(ISubject weatherData)
{
_weatherData = weatherData;
_weatherData.RegisterObserver(this);
}
public void Update(float temp, float humidity, float pressure)
{
_temprature = temp;
_humidity = humidity;
Display();
}
public void Display()
{
Console.WriteLine($"Statistics: {_temprature}F degrees and {_humidity}% humidity");
}
}
}