C#抽象工厂模式的几种实现方法及比较

2016-02-19 17:07 24 1 收藏

想要天天向上,就要懂得享受学习。图老师为大家推荐C#抽象工厂模式的几种实现方法及比较,精彩的内容需要你们用心的阅读。还在等什么快点来看看吧!

【 tulaoshi.com - 编程语言 】

  利用设计模式可以使我们的代码更灵活,更容易扩展,更容易维护。各种面向对象的程序设计语言都提供了基本相同的机制:比如类、继承、派生、多态等等。但是又有各自的特色,C# 中的反射机制便是一个很重要的工具,好好地利用就可以在实际中发挥很大的作用。

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  我们来看一个例子:

  我的程序中有需要一系列的对象,比如apple,orange, 要想利用他们,我们就必须在程序中根据用户要求,然后一个个调用 new 操作符来生成他们,这样客户程序就要知道相应的类的信息,生成的代码显然不够灵活。我们可以在代码中不利用具体的类,而只是说明我们需要什么,然后就能够得到我们想要的对象吗?

  哦,我们都看设计模式,听吧,很多人都在那里鼓吹他们是如何如何的棒,我们看看怎么样利用他们来解决问题。目标明确了,那我们看看哪个能够符合我们的要求。GoF的《设计模式》都看过吧,似懂非懂的看了一些,那我们看看能够不能够凑上去呢?J 嗯,我们的程序考虑的是对象怎么创建的,创建型模式应该符合要求吧。然后我们浏览一下各模式的意图部分。呵呵,第一个好像就撞到彩了,抽象工厂,我们看看吧,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类,至少无需指定它们具体的类符合我们的要求。来看看它的结构吧:

  我们的问题好像用不到这么复杂吧,只有orange,apple等等(应该就是product了),他们显然是一类的,都是fruit,我们只要一个生产水果的工厂就可以,左边的继承层次不要,只有一个FruitFactroy看看行不,先别管它正统不正统,实用就行J

  下面的一些东西显然是我们需要的:

  

Public interface IFruit{}public class Orange:IFruit{ public Orange() {  Console.WriteLine("An orange is got!"); }}public class Apple:IFruit{ public Apple() {  Console.WriteLine("An apple is got!"); }}

  我们的FruitFactory应该是怎么样呢?上面的结构图中它给的是CreateProductA,那好,我就MakeOrange,还有一个CreateProductB,俺MakeOrange还不行??

  

public class FruitFactory{ public Orange MakeOrange() {  return new Orange(); } public Apple MakeApple() {  return new Apple(); }}

  怎么使用这个工厂呢?我们来写下面的代码:

  

string FruitName = Console.ReadLine();IFruit MyFruit = null;FruitFactory MyFruitFactory = new FruitFactory();switch (FruitName){ case "Orange":  MyFruit = MyFruitFactory.MakeOrange();  break; case "Apple":  MyFruit = MyFruitFactory.MakeApple();  break; default:  break;}

  编译运行,然后在控制台输入想要的东西,呵呵,成功了。沉浸在幸福中的你得意忘形了吧。

  不过等等,它好像还不完美,我如果想要pear,我既要在客户代码中的switch中加入判断,又要在工厂方法中加入MakePear方法,好像不怎么优雅。更好一点,在工厂中只提供一个方法,MakeFruit,然后传递进一个参数Name,代表我们想要的水果的名称,这样的话,似乎我们的客户代码中的那个switch就可以不要了,相反,在FruitFactory中好像需要一个,还等什么呢?实现吧。

  

FruitFactory:public class FruitFactory{ public IFruit MakeFruit(string Name) {  switch (Name)  {   case "Orange":    return new Orange();   case "Apple":    return new Apple();   default:    return null;  } }} 

  客户代码:

  

string FruitName = Console.ReadLine();IFruit MyFruit;FruitFactory MyFruitFactory = new FruitFactory();MyFruit = MyFruitFactory.MakeFruit(FruitName);

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  这样看起来好多了,至少我客户代码中不要再写那么一长串的判断代码了。

  阿Q精神又在起作用,我们又沉浸在成功的喜悦中了。 嗯,代码好像可以,应该没有什么改进了。但是好像又有另外一个声音在说:

  除了一点

  嗯? 等等,什么?

  FruitFactory也有switch啊,看起来也ugly啊!

  哼,肯定是看《重构》或者是《TDD》了,怎么要求那么苛刻!反正闲着也是闲着,看看可以改不?

  既然不要条件判断,传入的只有水果的名称,假如Name = Apple,要生成一个Apple的对象,我需要new Apple(),如果我能够这样多好: new MakeItToClass(Name),把字符串转换成一个类。C#中虽然没有上述语法,但是提供了相应的机制,那就是反射。其中一个重要的类就是System.Type类,它对于反射起着核心的作用。我们可以使用 Type 对象的方法、字段、属性和嵌套类来查找有关该类型的所有信息。

  另外一个重要的类就是System.Activator,它包含特定的方法,用以在本地或从远程创建对象类型,或获取对现有远程对象的引用。

  我们可以先利用Type类获取Name指定的类名的类的Type信息,然后可以根据这个信息利用Activator创建对象。还等什么呢?

  

public class FruitFactory{ public IFruit MakeFruit(string Name) {  IFruit MyFruit = null;  try  {   Type type = Type.GetType(Name,true);   MyFruit = (IFruit)Activator.CreateInstance(type);  }  catch (TypeLoadException e)   Console.WriteLine("I dont know this kind of fruit,exception caught - {0}" ,e.Message);   return MyFruit; }} 

  经过这样的处理以后,增加新的水果的时候,我们不需要修改客户代码了,同时工厂的代码也不需要修改了,怎么样,爽吧!

来源:http://www.tulaoshi.com/n/20160219/1614266.html

延伸阅读
本文将给出通过 C# 编程来实现 忘记密码 功能的方法和代码,大家可以参照本文的思路自己写出这个功能代码…… 以下是引用片段: int result  = user.GetBackPassword(LoginName.Text.Trim(), Question.Text.Trim(),     Answer.Text.Trim(), Email.Text);   &nbs...
/*  FTPFactory.cs  Better view with tab space=4  Written by Jaimon Mathew (jaimonmathew@rediffmail.com)  Rolander,Dan (Dan.Rolander@marriott.com) has modified the  download  method to cope with file ...
标签: Web开发
C#实现文件拖放并打开文件 需要知道的ListBox的两个事件:当您在控件的边界内拖动对象时,便会发生 DragEnter 事件;该事件用于确 定当前拖动的对象是不是您要放到控件上的对象。 在将一个或多个文件拖到控件上时,需要处理此事件。 这使 得在将对象拖到控件上方时,能够根据所拖动的对象显示相应的图标。 将拖动的对象释放到控件上时,...
1. 概述 有时候我们需要在web页面上显示一张图,比如说一张地图,而这张地图会比较大。这时候如果我们把一张大图分隔成一组小图,那么客户端的显示速度会明显地感觉块。希望阅读本文对你有所帮助。 2. 实现思路 .NET Framework GDI+ 为我们提供了一组丰富地类来编辑图形图像。有关.NET Framework GDI+的...
介绍 很多有着不同开发背景得人都会比较熟悉单例模式。他们会发现每次他们要创建一个不同的单例类的时候,都不得不写同样得代码。使用新的C# 2.0的泛型,可以实现只写一次同样得代码。 使用 C# 2.0 泛型来完成单例模式的重用 使用 C# 2.0 的泛型,使得实现我所说的"单例提供者"成为可能。这是一个可用来创建单例...

经验教程

776

收藏

11
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部