觀察者模式

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);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 JavaScript 编写的简单俄罗斯方块游戏(附源代码) 项目:使用 JavaScript 编写的简单俄罗斯方块游戏(附源代码) 该游戏是一个使用 HTML5 和 JavaScript 开发的简单项目。这款游戏允许玩家策略性地旋转下落的方块以清除关卡。要在此游戏中得分,您必须通过操纵方块来清除线条,使它们填满水平行。当方块掉落时,您必须 根据需要移动 和旋转它们,使它们均匀地排列在底部。 游戏制作 该游戏仅使用 HTML、CSS 和 JavaScript。谈到这款游戏的功能,这款游戏的 PC 控制也很简单。首先,您必须按空格键才能开始游戏。您可以使用箭头键来更改下落方块的位置。您可以在侧栏看到形成的分数和行。 该游戏包含大量的 javascript,用于对游戏的某些部分进行验证。 如何运行该项目? 要运行此游戏,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox, 以获得更好、更优化的游戏体验。要玩游戏,首先,单击 index.html 文件在浏览器中打开游戏。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值