• 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();
            }
        }
    }
  • 相关阅读:
    C#.NET常见问题(FAQ)-如何在不同窗体之间传递值
    C#.NET常见问题(FAQ)-如何不显示窗口的关闭按钮
    C#.NET常见问题(FAQ)-如何判断两个类是否相同类型
    C#.NET常见问题(FAQ)-如何判断某个字符是否为汉字
    C#.NET常见问题(FAQ)-如何改变字符串编码
    C# 多线程编程 ThreadStart ParameterizedThreadStart
    C# 线程调用主线程中的控件
    LINQ to XML 编程基础
    LINQ to XML 建立,读取,增,删,改
    WinForm 自动完成控件实例代码简析
  • 原文地址:https://www.cnblogs.com/yzj1212/p/2639972.html
Copyright © 2020-2023  润新知