读书笔记6:工厂方法模式

来源:互联网 发布:淘宝秒杀技巧软件下载 编辑:程序博客网 时间:2024/05/11 16:16
1、概念

    定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法是一个类的实例化延伸到子类。

2、背景

    已经知道工厂模式,有一个父类SuperClass,以及这个父类的不同实现方法和算法的若干个子类ClassA,ClassB... ...,有一个工厂类DAOFactory,根据客户端传来的标识决定调用哪个子类。如下:

[csharp] view plaincopyprint?
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4.   
  5. namespace FactoryPattern  
  6. {  
  7.     public abstract class SuperClass  
  8.     {  
  9.         public abstract void GetResult();  
  10.     }  
  11.     public class ClassA:SuperClass  
  12.     {  
  13.         public override void GetResult()  
  14.         {  
  15.             Console.WriteLine("A类对GetResult()的实现。");  
  16.         }  
  17.     }  
  18.     public class ClassB : SuperClass  
  19.     {  
  20.         public override void GetResult()  
  21.         {  
  22.             Console.WriteLine("B类对GetResult()的实现。");  
  23.         }  
  24.     }  
  25.   
  26.     public class DAOFactory  
  27.     {  
  28.         static SuperClass super;  
  29.         public static SuperClass CreateSuperClass(string type)  
  30.         {  
  31.             switch (type)  
  32.             {  
  33.                 case "A":  
  34.                     super = new ClassA();  
  35.                     break;  
  36.                 case "B":  
  37.                     super = new ClassB();  
  38.                     break;  
  39.                 default:  
  40.                     break;  
  41.             }  
  42.             return super;  
  43.         }  
  44.     }  
  45. }  

客户端

[csharp] view plaincopyprint?
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4.   
  5. namespace FactoryPattern  
  6. {  
  7.     class Program  
  8.     {  
  9.         static void Main(string[] args)  
  10.         {  
  11.             SuperClass sup;  
  12.             sup = DAOFactory.CreateSuperClass("A");  
  13.             sup.GetResult();  
  14.    
  15.   
  16.             sup = DAOFactory.CreateSuperClass("B");  
  17.             sup.GetResult();  
  18.             Console.ReadLine();  
  19.         }  
  20.     }  
  21. }  

结果

 

可以看出,简单工厂模式是把到底实例化哪个类的逻辑放在工厂里判断,客户端不需要知道调用的哪个类,只关心结果就可以了。但是这里有一个问题,如果需求有了变化。那么就要增加新的类ClassC,ClassD… … 增加类不影响程序是可行的,但工厂类中的switch分支要不断地加,也就是要不断修改DAOFactory类,不符合开放封闭原则(程序实体可以扩展,但不被修改)。那么如何解决?

 3、工厂方法模式

    根据问题,可以有这样的方案,类ClassC,ClassD照常增加,但是需要修改工厂类。

[csharp] view plaincopyprint?
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4.   
  5. namespace FactoryPattern  
  6. {  
  7.     public abstract class SuperClass  
  8.     {  
  9.         public abstract void GetResult();  
  10.     }  
  11.   
  12.     public class ClassA:SuperClass  
  13.   
  14.     {  
  15.         public override void GetResult()  
  16.         {  
  17.             Console.WriteLine("A类对GetResult()的实现。");  
  18.         }  
  19.     }  
  20.     public class ClassB : SuperClass  
  21.     {  
  22.         public override void GetResult()  
  23.         {  
  24.             Console.WriteLine("B类对GetResult()的实现。");  
  25.         }  
  26.     }  
  27.   
  28.      public class ClassC : SuperClass  
  29.     {  
  30.         public override void GetResult()  
  31.         {  
  32.             Console.WriteLine("C类对GetResult()的实现。");  
  33.         }  
  34.     }  
  35.   
  36.     public class ClassD : SuperClass  
  37.     {  
  38.         public override void GetResult()  
  39.         {  
  40.             Console.WriteLine("D类对GetResult()的实现。");  
  41.         }  
  42.     }  
  43.   
  44.     public interface IFactory  
  45.     {  
  46.         SuperClass CreateSuperClass();  
  47.     }  
  48.   
  49.     public class AFactory : IFactory  
  50.     {  
  51.         public SuperClass CreateSuperClass()  
  52.         {  
  53.             return new ClassA();  
  54.         }  
  55.     }  
  56.   
  57.     public class BFactory : IFactory  
  58.     {  
  59.         public SuperClass CreateSuperClass()  
  60.         {  
  61.             return new ClassB();  
  62.         }  
  63.     }  
  64.   
  65.     public class CFactory : IFactory  
  66.     {  
  67.         public SuperClass CreateSuperClass()  
  68.         {  
  69.             return new ClassC();  
  70.         }  
  71.     }  
  72.     public class DFactory : IFactory  
  73.     {  
  74.         public SuperClass CreateSuperClass()  
  75.         {  
  76.             return new ClassD();  
  77.         }  
  78.     }  
  79. }  

客户端

[csharp] view plaincopyprint?
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4.   
  5. namespace FactoryPattern  
  6. {  
  7.     class Program  
  8.     {  
  9.         static void Main(string[] args)  
  10.         {  
  11.             IFactory factory;  
  12.             SuperClass sup;  
  13.             factory = new CFactory();  
  14.             sup = factory.CreateSuperClass();  
  15.             sup.GetResult();  
  16.   
  17.             factory = new DFactory();  
  18.             sup = factory.CreateSuperClass();  
  19.             sup.GetResult();  
  20.   
  21.               
  22.             Console.ReadLine();  
  23.         }  
  24.     }  
  25. }  

结果

这样,解决了修改分支的问题。但是把选择交给了客户端,需要客户端自己判断到底需要调用哪个类实现,如果需求变化客户端就需要修改。事物都是具有两面性的,因此到底使用哪种模式还需要在程序中视情况而定。

0 0