技术开发 频道

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

  不过等等,它好像还不完美,我如果想要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);
  这样看起来好多了,至少我客户代码中不要再写那么一长串的判断代码了。
 
  既然不要条件判断,传入的只有水果的名称,假如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;  } }
  经过这样的处理以后,增加新的水果的时候,我们不需要修改客户代码了,同时工厂的代码也不需要修改了。

0
相关文章