浅谈.NET独有精巧泛型设计模式

发表于:2012-5-09 09:52

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:小城故事    来源:51Testing软件测试网采编

  虽然泛型出现已有多年,连Java都早已借鉴引入了泛型(虽然是语法糖),可是用泛型的编程思维方式并没有得到相应的普及。一方面是由于过去大量的Framework仍然是在非泛型时代写成的,另一方面泛型的设计模式没有得到发展,改变的时候该到了。

  来举一个例子说明这两点。我们如果写过网络数据抓取的代码,应该熟悉这样的代码:

var request = WebRequest.Create("http://www.cnblogs.com/"as HttpWebRequest;

  或者这么写,也是一样:

var request = HttpWebRequest.Create("http://www.cnblogs.com/"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实现如下:

  1. class Image<T> where T:Image<T>, new()  
  2. {  
  3.     public string Path { getset; }  
  4.     public static T FromFile(string path)  
  5.     {  
  6.         return new T() { Path = path };  
  7.     }  
  8. }  
  9. class Bitmap:Image<Bitmap>  
  10. {  
  11. }

  Image自身的工厂方法,就没有存在的必要了。

  可以简单地测试一下:

  1. var path = @"e:\me.jpg";  
  2. var bm = Bitmap.FromFile(path); ;  
  3. Console.WriteLine(bm.Path);  
  4. Console.WriteLine(bm.GetType().Name);

  输出结果如下:

  1. Path: e:\me.jpg  
  2. Type: Bitmap

  为了让大家更熟悉一下,再举一个实现数据结构中的二叉树作例子。

  传统的树节点类,无论无论C/C++/Java都是类似这样:

  1. class TreeNode  
  2. {  
  3.     public TreeNode LeftChild { getset; }  
  4.     public TreeNode RightChild { getset; }  
  5.     public TreeNode Parent { getset; }  
  6.     public int Value { getset; }  
  7. }

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号