知识大全 .NET独有的精巧泛型设计模式
Posted 知
篇首语:带不走四季的风,就卷走一路的风景;遇不到心动的人,就孤身潇洒走四方。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 .NET独有的精巧泛型设计模式相关的知识,希望对你有一定的参考价值。
.NET独有的精巧泛型设计模式 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
在 NET发展史中 是具有里程碑意义的一个版本 从这个版本 NET青出于蓝(Java) 而胜于蓝 在 NET 带来的诸多新特性中 我认为泛型是最重要 没有之一 虽然泛型出现已有多年 连Java都早已借鉴引入了泛型(虽然是语法糖) 可是用泛型的编程思维方式并没有得到相应的普及 一方面是由于过去大量的Framework仍然是在非泛型时代写成的 另一方面泛型的设计模式没有得到发展 改变的时候该到了 来举一个例子说明这两点 我们如果写过网络数据抓取的代码 应该熟悉这样的代码 var request = WebRequest Create as HttpWebRequest; 或者这么写 也是一样 var request = HttpWebRequest Create as HttpWebRequest; 大家可想过 为什么每次都要as一下? 类似的情况还有 比如做图像处理的弟兄会熟悉 var bm = Image FromFile( e:\\\\me jpg ) as Bitmap; 和 var bm = Bitmap FromFile( e:\\\\me jpg ) as Bitmap; 我想过 但没想明白 上面两种写法 都是调用父类的工厂方法 实际返回了一个子类的实例 显然 即使不了解OCP 凭直觉也应该想到 父类的实现中不应该被子类所决定 写WebRequest和Image的前辈可能也觉得直接返回子类实例不妥 所以阴险地把方法签名的返回类型改成了父类 虽然这种行径值得严重鄙视 但 NET程序员大都是人云亦云 照葫芦画瓢的好学生 所以这个问题多年了也没有修改 理想的设计应该是这样 父类的每个子类 都有独立的工厂方法 返回其自身的实例 这样做法 在泛型出现前非常笨拙 得不偿失 但有了泛型 就可以精巧地实现 以模拟Image类为例 Image和BitMap实现如下 class Image<T> where T:Image<T> new() public string Path get; set; public static T FromFile(string path) return new T() Path = path ; class Bitmap:Image<Bitmap> Image自身的工厂方法 就没有存在的必要了 可以简单地测试一下 var path = @ e:\\me jpg ; var bm = Bitmap FromFile(path) ; Console WriteLine(bm Path) Console WriteLine(bm GetType() Name) 输出结果如下 Path: e:\\me jpg Type: Bitmap 为了让大家更熟悉一下 再举一个实现数据结构中的二叉树作例子 传统的树节点类 无论无论C/C++/Java都是类似这样 class TreeNode public TreeNode LeftChild get; set; public TreeNode RightChild get; set; public TreeNode Parent get; set; public int Value get; set; 大家知道 二叉树又分好几种 AVL树 B树 红黑树等等 实现特殊的二叉树数据结构 势必要继承TreeNode 由于树节点的类型中 有类型为基类的成员 所以在子类操作这些成员时 往往也要强制转换类型 这比Image和WebRequest的例子 只在实例创建时转换类型还麻烦 这就该泛型模式一显身手的好机会了 请看其父类型的实现 /// <typeparam name= T >Type of the node </typeparam> /// <typeparam name= K >Type of the node value </typeparam> class TreeNode<T K> where T:TreeNode<T K> where K: IComparable<K> public T LeftChild get; set; public T RightChild get; set; public T Parent get; set; public K Value get; set; 之后 实现任何一种特殊二叉树结构 比如RBTreeNode代表红黑树节点 可以这样 class RBTreeNode : TreeNode<RBTreeNode Int > /// <summary> /// 树节点颜色 是否为红 /// </summary> public bool IsRed get; set; public override string ToString() return this Value + + (this IsRed ? R : B ) 这个是AVL树 class AvlTreeNode : TreeNode<AvlTreeNode Int > /// <summary> /// 节点的平衡度 /// </summary> public int Balance get; set; public override string ToString() return Balance: + Balance + Value: + this Value; 不但完全符合OCP原则 而且再也不需要as来强制转换节点类型了 这肯定不是我的首创 其实 NET Framework中已经不少这样的设计 比如IComparable<T>接口 也有不少优秀的框架采用了类似的设计 比如大石头同学的ORM框架NewLife XCode 看上去也很简单吧 但是很多人思维还停留在面向对象语言刚诞生的阶段 还不习惯用这种设计模式 我认为这种写法足够典型和通用 足以得上一种设计模式 而且是 NET特殊优势 独特魅力 说到设计模式 其实GOF提出的 种设计模式多年了 已经过时 出现了许多新模式(比如并发编程方面 参考Wiki Design Pattern) 旧有的模式中 有的已经包含在 NET语言特性中 有的模式实现方式已经改头换面 尤其在泛型出现后 许多模式的实现可以变得简洁许多 优雅许多 不要一遍遍炒过去的冷饭 设计模式应该与时俱进 永远是充满新鲜活力的话题 cha138/Article/program/net/201311/13754相关参考