设计模式3实践——运用 C# 中的 delegate 简化设计模式的实现
2008-04-08 13:26
561 查看
在 C#语言对设计模式的支持中, delegate 是它很大的特色。delegate 可以将功能定义与功能实现分离,有利于设计职责分离的类结构。
delegate 的本质是函数指针。delegate 可以实现一个重要的概念是 callBack。什么是 callBack 呢?可以用一个简单的例子来说明: A 可以打电话告诉 B,要求 B 回个电话给 A。并且 A 在电话中可以规定 B 何时或何种情况下(这里的情况是指 A 观察的情况,而不是 B 出现何种情况。因为 A 不知道 B 的具体详情。)给你回电话,但电话内容由 B 决定。这样类 A 和 B 都可以有自己清晰的职责了。代码也就优雅灵活了。
-------------------------------------------------
delegate 是类型,必须先声明,再定义。然后才能使用。
声明:public delegate 返回值 委托名(参数列表).
定义: new 委托名(符合委托规范的方法或函数).
C#为了更灵活的支持这种 CallBack 的编程方法,在语言级别就声明了几种 delegate 。像基本数据类型,可以直接定义使用。
1、 Event :是种特殊的委托,有固定的返回值和参数列表。
2、 Func : 带有1个返回值的委托。有以下几种形式:
public delegate TResult Func<TResult>();
public delegate TResult Func<T1,TResult>(T1,TResult)
public delegate TResult Func<T1,...,Tn,TResult>(T1,...,Tn,TResult)
3、 Action: 没有返回值的委托。也有多种形式:
public delegate void Func<TResult>();
public delegate void Func<T1,...,Tn>(T1,...,Tn);
具体 Delegate 会运用哪些模式中?例如可以运用在 Template Method (模板方法) 中,运用 observer (观察者)模式等。
在传统的 Template Method 模式中要为每个 Method的实现开发一个子类。这就会带来子类过多的问题。于是可以利用 Delegate 在 Template 中定义抽象实现,在 客户端(应用环境)中实现具体的 Method 。这样既可以减少 Method 子类的数量,又可以达到具体实现与 Template 的解耦。
同样可以利用 delegate 消除 Observer 模式中接口的定义。
例子:
应用环境:
系统要实现给不同性质的目标发送短信:1、A群-要到tableA处取他们的电话号码;2、B群-要到tableB处取他们的电话号码。3、C 帐号-要到......得到手机号;4、D 手机号-直接输入手机号。
将来还有可能会其他的获取电话号码的手段。如何来设计我们的系统呢?如何面对以后的变化呢?
分析:
在这个流程中,虽然获取电话号码列表的方法不同,但是发送短信的流程是相同的。取得号码列表——判断列表——发送短信。问题现在就清除了,我们的变化点只是在取得号码列表的方法上。于是我们可以将发送短信的流程进行封装 Message.cs,通过 delegate 将如何取短信公布出来,因为如何取得号码列表只有发送的短信的人才是最清楚 MessageBiz 中封装了不同取得短信的方法。
应用:
这样之后我们只要在页面中将不同的取得短信的方法分配给 Message Class 就可以了。Message 中不会再有大量让人头痛的if else 了。更不用害怕以后有不同的取号方法,使得if else 越变越大,最后成为系统的累赘。
delegate 的本质是函数指针。delegate 可以实现一个重要的概念是 callBack。什么是 callBack 呢?可以用一个简单的例子来说明: A 可以打电话告诉 B,要求 B 回个电话给 A。并且 A 在电话中可以规定 B 何时或何种情况下(这里的情况是指 A 观察的情况,而不是 B 出现何种情况。因为 A 不知道 B 的具体详情。)给你回电话,但电话内容由 B 决定。这样类 A 和 B 都可以有自己清晰的职责了。代码也就优雅灵活了。
-------------------------------------------------
delegate 是类型,必须先声明,再定义。然后才能使用。
声明:public delegate 返回值 委托名(参数列表).
定义: new 委托名(符合委托规范的方法或函数).
C#为了更灵活的支持这种 CallBack 的编程方法,在语言级别就声明了几种 delegate 。像基本数据类型,可以直接定义使用。
1、 Event :是种特殊的委托,有固定的返回值和参数列表。
2、 Func : 带有1个返回值的委托。有以下几种形式:
public delegate TResult Func<TResult>();
public delegate TResult Func<T1,TResult>(T1,TResult)
public delegate TResult Func<T1,...,Tn,TResult>(T1,...,Tn,TResult)
3、 Action: 没有返回值的委托。也有多种形式:
public delegate void Func<TResult>();
public delegate void Func<T1,...,Tn>(T1,...,Tn);
具体 Delegate 会运用哪些模式中?例如可以运用在 Template Method (模板方法) 中,运用 observer (观察者)模式等。
在传统的 Template Method 模式中要为每个 Method的实现开发一个子类。这就会带来子类过多的问题。于是可以利用 Delegate 在 Template 中定义抽象实现,在 客户端(应用环境)中实现具体的 Method 。这样既可以减少 Method 子类的数量,又可以达到具体实现与 Template 的解耦。
同样可以利用 delegate 消除 Observer 模式中接口的定义。
例子:
应用环境:
系统要实现给不同性质的目标发送短信:1、A群-要到tableA处取他们的电话号码;2、B群-要到tableB处取他们的电话号码。3、C 帐号-要到......得到手机号;4、D 手机号-直接输入手机号。
将来还有可能会其他的获取电话号码的手段。如何来设计我们的系统呢?如何面对以后的变化呢?
分析:
在这个流程中,虽然获取电话号码列表的方法不同,但是发送短信的流程是相同的。取得号码列表——判断列表——发送短信。问题现在就清除了,我们的变化点只是在取得号码列表的方法上。于是我们可以将发送短信的流程进行封装 Message.cs,通过 delegate 将如何取短信公布出来,因为如何取得号码列表只有发送的短信的人才是最清楚 MessageBiz 中封装了不同取得短信的方法。
应用:
这样之后我们只要在页面中将不同的取得短信的方法分配给 Message Class 就可以了。Message 中不会再有大量让人头痛的if else 了。更不用害怕以后有不同的取号方法,使得if else 越变越大,最后成为系统的累赘。
相关文章推荐
- 《模式——工程化实现及扩展》(设计模式C# 版)《备忘录模式 Memento》——“自我检验"
- 设计模式之C#实现(四)---- ProtoType
- 设计模式的C#实现
- Android学习探索之运用MVP设计模式实现项目解耦
- C#中利用代理实现观察者设计模式详解
- C#简单工厂设计模式实现计算器
- 《设计模式--基于C#的工程化实现及扩展》补充 Security Design Pattern 系列 1 公钥体系与分布式环境要求
- 《模式——工程化实现及扩展》(设计模式C# 版)《原型模式 Prototype》——“自我检验"
- 【出版直播】博客园征途系列,《设计模式——基于C#的工程化实现及扩展》书签制作完成
- 【出版直播】博客园征途系列,《设计模式——基于C#的工程化实现与扩展》电子书、示例代码发布,互动网预订开始
- 《模式——工程化实现及扩展》(设计模式C# 版)《创建者模式 Builder》——“自我检验" 参考答案
- 《模式——工程化实现及扩展》(设计模式C# 版)《桥模式 Bridge》——“自我检验"参考答案
- 如何掌握并在实践中自如运用设计模式
- 《设计模式--基于C#的工程化实现及扩展》 Security Design Pattern 系列 1 公钥体系与分布式环境要求
- 设计模式:利用C#的Delegate来改进Observer模式
- 设计模式之C#实现--AbstractFactory
- 《设计模式--基于C#的工程化实现及扩展》补充 Security Design Pattern 系列 1 公钥体系与分布式环境要求
- 设计模式C#实现(五)——抽象工厂模式
- 设计模式C#实现(四)——迭代器模式
- .NET平台自带的AOP机制 转自《设计模式--基于c#的工程化实现及扩展》