觀察者模式

来源:互联网 发布:孟极序列号淘宝 编辑:程序博客网 时间:2024/06/05 13:21

OO原則:

為交互對象之間的松耦合設計而努力

 

OO模式:

觀察者模式(Observer),在對象之間定義一對多依賴,這樣一來,當一個對象改變狀態,依賴它的對象都會收到通知,并自動更新

 

類結構圖:

 

氣象站項目代碼

定義主體接口:

/// <summary>/// 定義主題對象接口/// </summary>public interface ISubject{    //註冊一個觀測者    void RegisterObserver(IObserver observer);    //移除一個觀測者    void RemoveObserver(IObserver observer);    //通知所有觀測者跟新數據    void NotifyObservers();    //設定是否通知觀測者更新    void SetChanged();}


定義觀測者接口:

/// <summary>/// 定義觀測者接口/// </summary>public interface IObserver{    //以拉的方式,主動從主題獲取所需要的數據    void Update(ISubject subject);    //以推的方式,被動接受主題傳來的信息    void Update(float temp, float humidity, float pressure);}

 

定義佈告板顯示接口:

/// <summary>/// 定義佈告板顯示接口/// </summary>public interface IDisplayElement{    void Display();}


WeatherData主體類:

using System.Collections;/// <summary>/// WeatherData 主題對象/// </summary>public class WeatherData : ISubject{    //訂閱者列表    private ArrayList observers;    //數據字段    private float temperature;    private float humidity;    private float pressure;    //是否通知觀測者更新    private bool changed = false;        public float Temperature    { get { return this.temperature; } }    public float Humidity    { get { return this.humidity; } }    public float Pressure    { get { return this.pressure; } }    //構造函數public WeatherData(){        observers = new ArrayList();}    //當從氣象站得到更新數據時,通知所有觀測者    public void MeasurementsChanged()    {        NotifyObservers();    }    //測試用模擬更新數據    public void SetMeasurements(float temperature, float humidity, float pressure)    {        this.temperature = temperature;        this.humidity = humidity;        this.pressure = pressure;        MeasurementsChanged();    }    #region 實現接口    //註冊觀測者    public void RegisterObserver(IObserver observer)    {        //加入觀測者        observers.Add(observer);    }    //註銷觀測者    public void RemoveObserver(IObserver observer)    {        //移除觀測者        int i = observers.IndexOf(observer);        if (i >= 0) {            observers.Remove(i);        }    }    //主題更新,通知所有觀測者    public void NotifyObservers()    {        if (changed)        {            foreach (IObserver observer in observers)            {                //調用每個觀測者的更新方法                //observer.Update(temperature, humidity, pressure);                observer.Update(this);            }            changed = false;        }    }    //設定是否通知觀測者更新    public void SetChanged()    {        changed = true;    }    #endregion}


第一號佈告板,目前狀況類:

/// <summary>/// CurrentConditionsDisplay 第一號佈告板:目前狀況/// </summary>public class CurrentConditionsDisplay : IObserver, IDisplayElement{    //觀測者持有主題引用    private ISubject subject;    //佈告板私有數據字段    private float temperature;    private float humidity;    private float pressure;    //構造函數public CurrentConditionsDisplay(ISubject subject){        this.subject = subject;}    //以拉的方式主動獲取數據    public void Update(ISubject subject)    {        WeatherData wd = subject as WeatherData;        if (wd != null)        {            this.temperature = wd.Temperature;            this.humidity = wd.Humidity;            this.pressure = wd.Pressure;            Display();        }    }    //以拖的方式被動接受數據    public void Update(float temp, float humidity, float pressure)    {        //throw new System.NotImplementedException();    }    //顯示信息    public void Display()    {        System.Web.HttpContext.Current.Response.Write("<br/>觀測者CurrentConditionsDisplay獲取新數據:"             + this.temperature + "," + this.humidity + "," + this.pressure);    }}


第二號佈告板,氣象統計類:

/// <summary>/// StatisticsDisplay 第二號佈告板:氣象統計/// </summary>public class StatisticsDisplay : IObserver, IDisplayElement{    //觀測者持有主題引用    private ISubject subject;    //佈告板私有數據字段    private float temperature;    //構造函數    public StatisticsDisplay(ISubject subject){        this.subject = subject;}    //以拉的方式主動獲取數據    public void Update(ISubject subject)    {        WeatherData wd = subject as WeatherData;        if (wd != null)        {            this.temperature = wd.Temperature;            Display();        }    }    //以拖的方式被動接受數據    public void Update(float temp, float humidity, float pressure)    {        //throw new System.NotImplementedException();    }    //顯示信息    public void Display()    {        System.Web.HttpContext.Current.Response.Write("<br/>觀測者StatisticsDisplay獲取新數據:"             + this.temperature);    }}


調用:

public partial class Observer : System.Web.UI.Page{    //主題對象    private static WeatherData wd = new WeatherData();    //觀測者    private static CurrentConditionsDisplay ccd;    private static StatisticsDisplay sd;    protected void Page_Load(object sender, EventArgs e)    {        if (!IsPostBack)        {            wd.SetChanged();            ccd = new CurrentConditionsDisplay(wd);            wd.RegisterObserver(ccd);            sd = new StatisticsDisplay(wd);            wd.RegisterObserver(sd);        }    }    protected void Button1_Click(object sender, EventArgs e)    {        wd.SetMeasurements(DateTime.Now.Second, DateTime.Now.Second + 1, DateTime.Now.Second + 2);    }}

 

原创粉丝点击