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

本文转自:http://hi.baidu.com/tufeivista/blog/item/2ca9702978dcc6fb99250a81.html

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

  我的程序中有需要一系列的对象,比如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);

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

  阿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;
 }
}

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

C#抽象工厂模式的几种实现方法及比较的更多相关文章

  1. Java设计模式(三) 抽象工厂模式

    原创文章,同步发自作者个人博客,转载请注明出处 http://www.jasongj.com/design_pattern/abstract_factory/ 抽象工厂模式解决的问题 上文<工厂 ...

  2. 设计模式(一): abstract factory抽象工厂模式 -- 创建型模式

    1.定义 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类. 2.适用场景 1.一个系统要独立于它的产品创建.组合和表示. 2.一个系统要由多个产品系列中的一个来配置. 3.当你要 ...

  3. 抽象工厂模式和autofac的使用总结

    抽象工厂模式和依赖注入的使用目的都是降低对象直接依赖耦合关系,应该说依赖注入是抽象工厂模式的一种升华,功能更强大. 说到抽象工厂的模式,一般都要先解释下简单工厂,简单工厂就是将对象的实例化抽取出来形成 ...

  4. Java设计模式—工厂方法模式&抽象工厂模式

    工厂方法模式与抽象工厂模式都是设计模式中重要而且常见的模式.       工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 通用类图如下: 在 ...

  5. JAVA中的工厂方法模式和抽象工厂模式

    工厂方法模式: 定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类.类型:创建类模式类图: 类图知识点:1.类图分为三部分,依次是类名.属性.方法2.以& ...

  6. Java设计模式学习笔记(四) 抽象工厂模式

    前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 1. 抽象工厂模式概述 工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问 ...

  7. 抽象工厂模式(JAVA反射)

    实例代码(JAVA):模式动机     在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方 ...

  8. java23种设计模式(一)-- 工厂模式、抽象工厂模式和单例模式

    一.工厂模式 1.定义统一的接口,并在接口中定义要实现的抽象方法. 2.创建接口的具体实现类,并实现抽象方法. 3.创建一个工厂类,根据传递的参数,生成具体的实现类对象,执行具体的方法. 优点: 1. ...

  9. php 23种设计模型 - 抽象工厂模式

    抽象工厂模式(AbstractFactory) 抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂.该超级工厂又称为其他工厂的工厂.这种类型的设计模式属于创 ...

随机推荐

  1. HDU4908——BestCoder Sequence(BestCoder Round #3)

    BestCoder Sequence Problem DescriptionMr Potato is a coder.Mr Potato is the BestCoder.One night, an ...

  2. ASP.NET树形控件TreeView的递归绑定

    来自:http://blog.csdn.net/xqf003/article/details/4958727

  3. 如何在VS2010中使用Async功能?

    伴随C#5.0的发布,“异步”特性越来越深入人心:在VS2012中早就可以使用它大大简化异步编程的痛苦,那么在VS2010中呢?我们无法尝鲜么?答案是“No”!,其实我们可以这样做: 1)必须把你的V ...

  4. Vim 配色设置与配色脚本语法

    几个给tag加颜色的插件 https://github.com/octol/vim-cpp-enhanced-highlight:基于tag的c family语法高亮 https://github.c ...

  5. JavaScript DOM高级程序设计 2.4-try{}catch{}--我要坚持到底!

    先看一段有异常的语句 var sound = 'Roar!'; function myOrneryBeast() { this.style.color='green';//window没有style属 ...

  6. 2013 ACM/ICPC Asia Regional Changsha Online - G(DP)

    第一眼就想到DP,然后想了N久就想不到可以不重算的DP  最后没办法了 先算出来 再去重.. 因为最多只有三个 对于三个来说有三种组合情况 x+y+z, x*y*z, x*y+z 那要么 x,y,z都 ...

  7. 安装nging,php

    http://www.zihou.me/html/2010/11/14/2658.html http://www.linuxidc.com/Linux/2011-04/34964p4.htm http ...

  8. poj3321

    树映射到树状数组上 非常好的题目,给了我很多启发 题目要求动态求一个棵子树的节点个数 不禁联想到了前缀和,只要我们能用一个合适的优先级表示每个顶点,那么就好做了 我们可以考虑将子树表示成区间的形式 这 ...

  9. DataView.RowFilter筛选DataTable中的数据

    //定义一个DataView ,得到一个全部职员的视图DataView dataView1 = DbHelperSQL.QueryDataView(sql); //过滤得到一个只显示男职员的视图 da ...

  10. 【 D3.js 高级系列 — 5.0 】 颜色

    颜色是作图不可少的概念,常用的标准有 RGB 和 HSL,D3 提供了创建颜色对象的方法,能够相互转换和插值. RGB色彩模式是通过对红(Red).绿(Green).蓝(Blue)三个颜色通道相互叠加 ...