Observer设计模式-------3

Observer设计模式主要包括两类对象:

1.Subject:监视对象,其往往包含其他对象感兴趣的内容。在烧水报警模型中,热水器就是一个监视对象。它包含其他对象感兴趣的内容,temprature字段。

2.Observer:监视者,他见识Subject,当Subject中某事件发生时,会告知Observer,而Observer会采取相应行动。

在烧水报警中事情发生顺序:

1.警报器和显示器告诉热水器,它对它的温度感兴趣(注册)。

2.热水器知道后保留对警报器和显示器的引用。

3.热水器进行烧水这一动作,当水温超过95度,通过警报器和显示器的引用,自动调用警报器和显示器中相应方法。

using System;
using System.Collections.Generic;
using System.Text;

namespace  Delegate
{
    //热水器
    public class Heater
    {
        private int temperature;

        public delegate void BoilHandler(int param);//声明委托
        public event BoilHandler BoilEvent;//声明事件
        //烧水
        public void BoilWater()
        {
            for(int i=0;i<=100;i++)
            {
                temperature = i;
                if(temperature>95)
                {
                    if(BoilEvent!=null)
                    {
                        BoilEvent(temperature);
                    }
                }
            }
        }
    }
    //警报器
    public class  Alarm
    {
        public void MakeAlert(int param)
        {
            Console.WriteLine("Alarm:嘀嘀嘀,水已经{0}度了",param);
        }
    }
    //显示器
    public class Display
    {
        public static void ShowMsg(int param)
        {
            Console.WriteLine("Display:嘀嘀嘀,水已经{0}度了", param);
        }
    }

    class Program
    {
        static void Main()
        {
            Heater heater = new Heater();
            ;
            Alarm alarm=new Alarm();
            //heater.BoilEvent += alarm.MakeAlert;
            heater.BoilEvent += (new Alarm()).MakeAlert;
            heater.BoilEvent += Display.ShowMsg;

            heater.BoilWater();
        }
    }
}

framework编码规范:

1.委托类型的名称都应该依EventHandler结束。

2.委托的原型第一:有一个void返回值,并接受两个输入参数:一个Object类型,一个EventArgs类型(或继承自EventArgs)。

3.事件的命名为委托去掉EventHandler之后剩余的部分。

4.继承自EvenArgs的类型应该以EventArgs结尾。

结合上面例子

委托原型中的Object类型的参数代表了Subject,即监视对象,本例中时Heater。回调函数(如Alarm的MakeAlert)可以通过它访问触发事件的对象(Heater)。

EventArgs对象包含了Observer所感兴趣的数据,在本例中时temperature

using System;
using System.Collections.Generic;
using System.Text;

namespace  Delegate
{
    //热水器
    public class Heater
    {
        private int temperature;
        public string type = "RealFire 001";
        public string area = "China Xian";
        public delegate void BoilEventHandler(Object sender,BoiledEventArgs e);//声明委托
        public event BoilEventHandler Boiled;//声明事件
        //定义BoiledEventArgs类,传输给Observer所感兴趣的信息
        public class BoiledEventArgs:EventArgs
        {
            public readonly int temperature;
            public BoiledEventArgs(int temperature)
            {
                this.temperature = temperature;
            }
        }
        //可以供继承自Heater的类重写,以便继承类拒绝其他对象对它的监视
        protected virtual void OnBoiled(BoiledEventArgs e)
        {
            if(Boiled!=null)
            {
                Boiled(this, e);
            }
        }
        //烧水
        public void BoilWater()
        {
            for(int i=0;i<=100;i++)
            {
                temperature = i;
                if(temperature>95)
                {
                    BoiledEventArgs e=new BoiledEventArgs(temperature);
                    OnBoiled(e);
                }
            }
        }
    }
    //警报器
    public class  Alarm
    {
        public void MakeAlert(Object sender,Heater.BoiledEventArgs e)
        {
            Heater heater = (Heater) sender;
            //访问sender中的公共字段
            Console.WriteLine("Alarm:嘀嘀嘀,水已经{0}度了", e.temperature);
        }
    }
    //显示器
    public class Display
    {
        public static void ShowMsg(Object sender, Heater.BoiledEventArgs e)
        {
            Heater heater = (Heater)sender;
            Console.WriteLine("Display:嘀嘀嘀,水已经{0}度了", e.temperature);
        }
    }

    class Program
    {
        static void Main()
        {
            Heater heater = new Heater();
            ;
            Alarm alarm=new Alarm();
            //heater.BoilEvent += alarm.MakeAlert;
            heater.Boiled += (new Alarm()).MakeAlert;
            heater.Boiled += new Heater.BoilEventHandler(alarm.MakeAlert);//也可以这么注册
      
            heater.Boiled += Display.ShowMsg;

            heater.BoilWater();
        }
    }
}

 

 

 

posted @ 2012-08-15 13:57  yzj1212  阅读(113)  评论(0编辑  收藏  举报