运用工厂模式

     工厂模式可能是我们最常遇见和使用的设计模式, 如果把工厂模式以及其实现部分看成是一个黑盒子,那么我们只需要告诉它我所需要的对象(注意:我不知道这个对象是如何实现的), 我们即可得到该对象.

工厂模式可以细分为三种, 即: 简单工厂模式, 工厂方法模式, 虚拟工厂模式.

简单工厂模式(Simple Factory Pattern):


如图所示,简单工厂达到了将类的实例化封装的效果.  因为对同类class的解藕, 黑盒子外面我们能看到的ClassFactory和BaseClass借口. 把代码:
     SubClassA aEntity=new SubClassA();
     SubClassB bEntity=new SubClassB();
转换成了:
     BaseClass xEntity=ClassFactory.Create(A);
     BaseClass xEntity=ClassFactory.Create(B);

这样,我们可以通过统一的方法调用来实现不同的功能.

     xEntity.DoSomeThing();

在我们只知道前提为A的情况下它调用了
     SubClassA.DoSomeThing();

而在只知道前提为B的情况下调用:
     SubClassB.DoSomeThing();

于是在黑盒子外的我们,只需要考虑A和B的不同情况,而不需要想A情况会怎么样,B情况如何操作了.

 

工厂方法模式(Factory Method Pattern)

 

 留意工厂方法模式的类结构图,它和上面的简单工厂模式有什么样的区别?

    单看ClassFactoryA和ClassFactoryB,它们实际上就是两个简单工厂模式.因为ClassFactoryA和ClassFactoryB都是实现了BaseClass的创建过程,  所以它们是对同类对象的创建工厂.  于是提取出ClassFactoryA和ClassFactoryB的共性,  将它们归类到BaseClassFactory接口,   就实现了工厂方法模式.

 看一个工厂方法模式的例子:

Code

 

在工厂方法模式中, 具体功能的实现依然是在其所包含的两个简单工厂的结构中, 不同的是对于前文所示的A,B两种条件,工厂方法做了更细的细分.c#中datacommand就是使用的工厂方法模式. datacommand中细分为SqlDataCommand, OledbDataCommand等, 它们都是实现了DataCommand接口的具体的工厂, 同时在这两个工厂中, 我们可以选择CommandType为Queue或者SavedProcedure. 这便是在工厂中选择创建那种对象的条件A和B. 这样,我们就可以通过
工厂方法模式创建适用于何种数据库,何种查询方式的command对象.

 

虚构工厂模式(Abstract Factory Pattern)

     虚构工厂模式较以上两种模式更佳复杂,  它将不同系列, 却以不同方式完成类似功能的类别进行系列的划分.如下图所示.

 

                                          Abstruct Factory

BaseClass1, BaseClass2和BaseClass3是互相联系的类别,它们的共同作用能完成一定功能的任务, 因为环境条件的不同,我们需要在这3个类中继承出不同的类别系列来完成任务,而这些系列被归纳到ClassFactoryA和ClassFactoryB.因为ClassFactoryA和ClassFactoryB完成的功能类似,所以我们定义了BaseClassFactory父类, 同时将这些共同的功能封装在其中.这样就形成了虚拟工厂模式. 程序示例如下:

 

Code


从结构图你也许会觉得虚拟工厂模式和工厂方法模式区别不大,只是虚拟工厂模式中同时实现了多个BaseClass的方法而已. 其实不然, 结构图的区别说明的是虚拟工厂模式强调的是系列与系列间的解藕, 而工厂方法的维度更细微一些. 同时它们在实现的方法上也不同.

工厂方法模式将实例化推迟到子类, 在黑盒子外面我们仍将具体的class视为操作的主体, 这样我们只要通过派生出不同的工厂类继承工厂的接口,而派生于BaseClass的子类我们有足够的灵活度来重写它的实现.

     foreach (Page page in document.Pages)
        {
          Console.WriteLine(
" " + page.GetType().Name);
        }

虚拟工厂模式中, 工厂接口使用虚拟工厂将其子工厂的功能进行了归纳总结,它使得我们在实现虚拟工厂的时候子结构更严禁稳定.

     ContinentFactory africa = new AfricaFactory();
      AnimalWorld world 
= new AnimalWorld(africa);
      world.RunFoodChain();


注意比较在工厂方法模式中我们使用的Page和在虚拟工厂中使用的World之间的区别.

 

只有清楚了解才能妥善使用,只有通过使用才能更加了解. 这是我对工厂模式的理解, 欢迎大家共同交流, 不怕挨砖头.

posted @ 2008-11-03 15:30  Zero.Li  阅读(589)  评论(0编辑  收藏  举报