前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式(2):观察者模式-2 (委托、事件)

设计模式(2):观察者模式-2 (委托、事件)

作者头像
用户2434869
发布2018-09-12 10:31:19
4930
发布2018-09-12 10:31:19
举报
文章被收录于专栏:yl 成长笔记yl 成长笔记

一: 基本概念

1、委托(Delegate)

概念:对某个方法引用的一种引用类型变量。注意看概念, 委托是一种引用类型变量, 类型变量,因此可以将委托当作方法的参数进行传递。 通俗点来讲,委托有点像方法的快捷方式, 通过委托可以执行方法。

声明: 在类中声明, 其声明决定了该委托可用的方法。也就是说,委托只可指向具有相同标签(参数、返回值)的方法。

举个例子:

代码语言:javascript
复制
1 // 声明委托
2 public delegate double MyDelegate(string s);
3 // 创建方法
4 public double GetStart(string testString);
5 // 实例化委托, 调用的方法需与委托有相同的参数、返回值
6 MyDelegate delegate = new MyDelegate(GetStart);

2、事件(Event)

概念: 当某个类(发布者 Publisher)的某些特定状态改变时,发送通知给所有关心它这个变化的其它类(订阅者 Subscriber),并触发相关类中的相关函数。如按键、点击等都是事件。

发布者: 决定什么时候触发事件。包含事件与委托的定义与声明,执行绑定了事件的方法(订阅者类中方法)。

订阅者: 决定做什么事(提供具体方法)。 接受事件并提供事件处理程序的对象。

事件声明:

代码语言:javascript
复制
1 // 先声明事件的委托类型, 事件在生成时会调用委托
2 public delegate void MyDelegateEventHandler(object sender, EventArgs e);
3 public event MyDelegateEventHandler MyEvent;

二、事件在观察者模式中的应用

举一个《Head First 设计模式》 上的经典应用,附件上有完整的代码。

需求如下: 建立一个气象观测站,该气象站建立在 WeatherData 对象上, 由 WeatherData 对象负责追踪目前的天气状况(温度、湿度、气压)。我们要建立一个应用,有三种(或更多)布告板, 分别显示目前的状况、气象统计以及简单的预报。当 WeatherDataObject 对象获得最新的测量数据时, 三种布告板必须实时更新。并且希望这个气象站的扩展性良好。

1、创建发布者类

代码语言:javascript
复制
 1     // 发布者类
 2     public class WeatherData
 3     {
 4         // 声明事件
 5         public  delegate void WeatherChangeEventHandler(object sender, WeatherChangeArgs e);
 6         public event WeatherChangeEventHandler WeatherChange;
 7 
 8         // 虚函数,使得派生类可重写触发事件的标准
 9         protected  virtual void onWeatherChange(WeatherChangeArgs e)
10         {
11             WeatherChange?.Invoke(this, e);
12         }
13          // 事件一定要在方法中执行
14         public  void RaiseWeatherChange(WeatherChangeArgs e)
15         {
16             onWeatherChange(e);
17         }
18     }
19 
20     // 创建一个事件类, 提供我们关心的数据的值
21     public class WeatherChangeArgs : EventArgs
22     {
23         public  readonly double temperature;
24         public  readonly double humidity;
25         public  readonly double pressure;
26         public WeatherChangeArgs(double temperature, double humidity, double pressure)
27         {
28             this.temperature = temperature;
29             this.humidity = humidity;
30             this.pressure = pressure;
31         }
32     }

2、创建订阅者类

订阅者数量众多,为了统一管理,需创建一个统一的接口,这也符合 OO 的原则, 面向接口编程。

代码语言:javascript
复制
 1 // 创建订阅者统一接口 
 2     public interface IWeatherStationSubject
 3     {
 4         void Display(object sender, WeatherChangeArgs e);
 5     }
 6 
 7 // 当前状况显示面板
 8   public class CurrentConditionDisplay : IWeatherStationSubject
 9     {
10         public  void Display(object sender, WeatherChangeArgs e)
11         {
12             Console.WriteLine("Current conditons:" + e.temperature + "degreees and " + e.humidity + "% humidity" );
13         }
14     }
15 // 未来预测天气状况显示面板
16     public class ForecastDisplay : IWeatherStationSubject
17     {
18         public void Display(object sender, WeatherChangeArgs e)
19         {
20             Console.WriteLine("Tomorrow weather condition: " + e.temperature*1.1 + " degree ," + e.humidity*0.9 + "% humidity");
21         }
22     }
23 
24 // 个人情绪状态预测
25     public class ForecastDisplay : IWeatherStationSubject
26     {
27         public void Display(object sender, WeatherChangeArgs e)
28         {
29             Console.WriteLine("Tomorrow weather condition: " + e.temperature*1.1 + " degree ," + e.humidity*0.9 + "% humidity");
30         }
31     }

3、为了实现订阅系统与主控制系统松耦合, 创建订阅系统

代码语言:javascript
复制
1     public class WeatherSubscriberSystem
2     {
3         public WeatherSubscriberSystem(WeatherData weatherData, WeatherChangeArgs e)
4         {
5             weatherData.WeatherChange += new WeatherData.WeatherChangeEventHandler((new CurrentConditionDisplay()).Display);
6             weatherData.WeatherChange += (new ForecastDisplay()).Display;
7             weatherData.WeatherChange += (new FeelingToneDisplay()).Display;
8             weatherData.RaiseWeatherChange(e);
9         }

 4、 主控制系统

代码语言:javascript
复制
 1   class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             WeatherSubscriberSystem sys_1 = new WeatherSubscriberSystem(new WeatherData(), new WeatherChangeArgs(20, 18.6, 55));
 6             Console.WriteLine("\n");
 7             WeatherSubscriberSystem sys_2 = new WeatherSubscriberSystem(new WeatherData(), new WeatherChangeArgs(35, 24, 38));
 8             Console.ReadKey();
 9         }
10     }

至此整个系统完成了。我们可以发现,用 .net 内置的事件来实现观察者模式,比自己实现更简单,控制起来也更方便。

点击下载完整代码

参考:http://www.cnblogs.com/wudiwushen/archive/2010/04/21/1717378.html

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-10-19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档