欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

观察者模式与.Net Framework中的委托与事件

程序员文章站 2022-07-05 17:32:48
本文文字内容均选自《大话设计模式》一书。 解释:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。 此模式又叫发布-订阅模式。 举例:火车到站与乘客下车。 主题: 观察者1: 观察者2: 客户端: ......

   本文文字内容均选自《大话设计模式》一书。

    解释:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

    此模式又叫发布-订阅模式。

    举例:火车到站与乘客下车。

    主题:

 1 using system;
 2 using system.threading;
 3 
 4 namespace delegatedemo2
 5 {
 6     public class 高速列车
 7     {
 8         public string 车次 { get; set; }
 9         private string[] 途经车站;
10         private string 当前到站;
11 
12         public delegate void 到站eventhandler(object sender, 到站eventargs e);
13         public event 到站eventhandler 到站;
14 
15         public class 到站eventargs : eventargs
16         {
17             public readonly string 当前到站;
18             public 到站eventargs(string 当前到站)
19             {
20                 this.当前到站 = 当前到站;
21             }
22         }
23 
24         public 高速列车()
25         {
26             this.车次 = "g253";
27             this.途经车站 = new string[] { "青岛站", "济南站", "泰安站", "徐州站", "南京站", "苏州站", "杭州站" };
28         }
29 
30         protected void on到站(到站eventargs e)
31         {
32             if (this.到站 != null)
33             {
34                 this.到站(this, e);
35             }
36         }
37 
38         public void 行驶()
39         {
40             for (int i = 0; i < this.途经车站.length; i++)
41             {
42                 this.当前到站 = this.途经车站[i];
43                 到站eventargs e = new 到站eventargs(this.当前到站);
44                 on到站(e);
45 
46                 thread.sleep(1000 * 3);
47             }
48         }
49     }
50 }

    观察者1:

 1 using system;
 2 
 3 namespace delegatedemo2
 4 {
 5     public class 显示器
 6     {
 7         public void 显示到站信息(object sender, delegatedemo2.高速列车.到站eventargs e)
 8         {
 9             高速列车 高速列车 = (高速列车)sender;
10             console.writeline("{0}次列车当前已到达{1}。", 高速列车.车次, e.当前到站);
11         }
12     }
13 }

    观察者2:

using system;

namespace delegatedemo2
{
    public class 乘客
    {
        public string 姓名 { get; set; }
        public string 目的地 { get; set; }

        public 乘客(string 姓名, string 目的地)
        {
            this.姓名 = 姓名;
            this.目的地 = 目的地;
        }

        public void 提行李下车(object sender, delegatedemo2.高速列车.到站eventargs e)
        {
            if (e.当前到站 == this.目的地)
            {
                console.writeline("乘客({0})已到达目的地{1},提行李下车!", this.姓名, e.当前到站);
            }
        }
    }
}

    客户端:

 1 namespace delegatedemo2
 2 {
 3     class program
 4     {
 5         static void main(string[] args)
 6         {
 7             高速列车 高速列车 = new 高速列车();
 8             显示器 显示器 = new 显示器();
 9 
10             乘客 张三丰 = new 乘客("张三丰", "济南站");
11             乘客 风清扬 = new 乘客("风清扬", "南京站");
12             乘客 扫地僧 = new 乘客("扫地僧", "杭州站");
13 
14             高速列车.到站 += new 高速列车.到站eventhandler(显示器.显示到站信息);
15             高速列车.到站 += new delegatedemo2.高速列车.到站eventhandler(张三丰.提行李下车);
16             高速列车.到站 += new delegatedemo2.高速列车.到站eventhandler(风清扬.提行李下车);
17             高速列车.到站 += new delegatedemo2.高速列车.到站eventhandler(扫地僧.提行李下车);
18 
19             高速列车.行驶();
20         }
21     }
22 }

    使用情景:当一个对象的改变需要同时改变其他对象,且不知道具体有多少对象有待改变时,应该考虑使用观察者模式。

    【委托】:委托可以看作是对函数的抽象,是函数的“类”,委托的实例将代表一个具体的函数。

    一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。

    而且,一个委托可以搭载多个方法,所有方法被依次唤起。更重要的是,它可以使得委托对象所搭载的方法并不需要属于同一个类。