zoukankan      html  css  js  c++  java
  • C#基础笔记——委托(Delegate)和事件(Event)

    一、概述

    委托首先是一个方法指针。

    委托也是一个类,当对其进行实例化的时候,要将引用方法作为它的构造方法的参数。

    事件是为委托施加保护的,它封装了委托类型的变量,使得在类的内部,不管你声明它是public还是protected,它总是private的。在类的外部,注册“+=”和注销“-=”的访问限定符与你在声明事件时使用的访问符相同。

    二、委托和事件的使用及Observer设计模式:

    Observer设计模式:Observer设计模式是为了定义对象间的一种一对多的依赖关系,以便于当一个对象的状态改变时,其他依赖于它的对象会被自动告知并更新。Observer模式是一种松耦合的设计模式。

    我们用Observer设计模式实现高档的热水器烧水过程,给它通上电,当水温超过95度的时候:

      1、扬声器会开始发出语音,告诉你水的温度;

      2、液晶屏也会改变水温的显示,来提示水已经快烧开了,同时显示热水器厂家名称。

    现在我们需要写个程序来模拟这个烧水的过程,我们将定义一个类来代表热水器,我们管它叫:WaterHeater,它有代表水温的字段,叫做temperature;当然,还有必不可少的给水加热方法heatUp()。一个发出语音警报的类Alarm和一个显示类Screen,他们继承Observer抽象类。

    首先我们需要一个热水器类:

        public delegate void ActionEventHandler(object sender, ConcernEventArgs e);
    
        public class WaterHeater
        {
            public event ActionEventHandler action;
    
            private string manufacturer ;
    
            public string Manufacturer
            {
                get { return manufacturer; }
                private set { manufacturer = value; }
            }
    
            public WaterHeater(string manufacturer)
            {
                this.manufacturer = manufacturer;
            }
    
            public void attach(Observer observer)
            {
                action += observer.display;
            }
            public void detach(Observer observer)
            {
                action -= observer.display;
            }
    
            public static WaterHeater getInstance(string manufacturer)
            {
                return new WaterHeater(manufacturer);
            }
    
            public void heatUp()
            {
                for (int i = 0; i <= 100; i++)
                {
                    if (i > 95)
                    {
                        ConcernEventArgs e = new ConcernEventArgs(i,this.manufacturer);
    
                        action.DynamicInvoke(this, e);
    
                    }
                }
            }
        }

    然后是一个标准的事件模型:

    事件模型规范:

    1. 委托类型名称以EventHandler结束;

    2. 原型返回值为void;

    3. 事件原型具有两个参数:sender表示事件触发者,e表示事件参数;

    4. 事件参数名称要以EventArgs结束;

        public class ConcernEventArgs : EventArgs
        {
            internal readonly int temprature;
            internal readonly string manufactor;
    
            public ConcernEventArgs(int temprature, string manufactor)
            {
                this.temprature = temprature;
                this.manufactor = manufactor;
            }
        }

    此时我的热水器类就完成了。

    我们还需要一个观察者Observer抽象类

    public abstract class Observer
        {
            public abstract void display(object sender, ConcernEventArgs e);
        }

    实现Alarm类继承Observer抽象类重写display方法:

        public class Alarm:Observer
        {
            public static Alarm getInstance()
            {
                return new Alarm();
            }
    
            public override void display(object sender, ConcernEventArgs e)
            {
                Console.WriteLine("Alarm:" + e.manufactor);
                Console.WriteLine("Alarm:"+e.temprature );
            }
        }

    实现Screen类继承Observer抽象类重写display方法:

        public class Screen : Observer
        {
            public static Screen getInstance()
            {
                return new Screen();
            }
    
            public override void display(object sender, ConcernEventArgs e)
            {
                Console.WriteLine("Screen:" + e.manufactor);
                Console.WriteLine("Screen:" + e.temprature);
            }
        }

    下面我们用控制台程序实现热水器烧水过程:

        class Program
        {
            static void Main(string[] args)
            {
                Alarm alarm = Alarm.getInstance();
                Screen screen = Screen.getInstance();
                WaterHeater waterHeater = WaterHeater.getInstance("BOB");
                waterHeater.attach(alarm);
                waterHeater.attach(screen);
                waterHeater.heatUp();
                Console.ReadKey();
            }
        }

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

    Subject:主题对象,它往往包含着其他对象所感兴趣的内容。在本范例中,热水器就是一个监视对象,它包含的其他对象所感兴趣的内容,就是temprature字段,当这个字段的值快到100时,会不断把数据发给监视它的对象。

    Observer:监视者,它监视Subject,当Subject中的某件事发生的时候,会告知Observer,而Observer则会采取相应的行动。在本范例中,Observer有警报器和显示器,它们采取的行动分别是发出警报和显示水温。

    在本例中,事情发生的顺序应该是这样的:

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

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

    3.热水器进行烧水这一动作,当水温超过95度时,通过对警报器和显示器的引用,自动调用警报器的display()方法、显示器的display()方法。

  • 相关阅读:
    Elementary Methods in Number Theory Exercise 1.3.13
    Elementary Methods in Number Theory Exercise 1.3.17, 1.3.18, 1.3.19, 1.3.20, 1.3.21
    数论概论(Joseph H.Silverman) 习题 5.3,Elementary methods in number theory exercise 1.3.23
    Elementary Methods in Number Theory Exercise 1.2.31
    数论概论(Joseph H.Silverman) 习题 5.3,Elementary methods in number theory exercise 1.3.23
    Elementary Methods in Number Theory Exercise 1.3.13
    Elementary Methods in Number Theory Exercise 1.3.17, 1.3.18, 1.3.19, 1.3.20, 1.3.21
    Elementary Methods in Number Theory Exercise 1.2.31
    Elementary Methods in Number Theory Exercise 1.2.26 The Heisenberg group
    4__面向对象的PHP之作用域
  • 原文地址:https://www.cnblogs.com/Abel-Zhang/p/DelegateAndEvent.html
Copyright © 2011-2022 走看看