设计模式-创建型-工厂模式(FACTORY METHOD)

  根据gof的设想,工厂方法模式被定义成了推迟实例化到子类的一种手段。“定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类”。

  以下是对工厂模式的结构解析。

  

 

  正如从图里能读到的,工厂模式的初始愿意并没有规定一个特殊的抽象方法Create或者类似方法。工程模式的关键点在于延迟对象的实例化。这样做乍看起来完全是没有必要的,因为这样做的最直观的影响就是增加了类的个数。我们能预料得到的结果就是,当我们需要获取一个新的类型的对象时,要做的第一件事就是新增加一个product类的子类和一个creator类的子类,将原本只需要直接实例化product子类就能达到目的的实现变成了需要新增加一个子creator类并推迟到了它的成员函数来实现。但是需要注意的是,所有让软件结构更易维护更易拓展的策略都是需要代价的。很明显这里的代价就是可能无限制增加的product和creator。

  就笔者的理解来说,工厂方法模式的优势在于。

  1. 为客户获取product类对象提供了一个新的抽象,这个抽象的名字叫creator。

    这里的客户可以是一个类可以是一个方法,视情况而定。提供一个新的抽象方法的好处是显而易见的,最直观的就是提供了一个可被重载的新类。这个新类的作用类似于hook函数,只不过它继承了面向对象语言的优点,灵活性与可拓展性。对于客户来说,需要打交道的不再是product,而是creator。如书上的这个例子所描述的那样(如下图)。这里的Application类就是creator,MyApplication类就是concreteCreator, Document就是product,MyDocument就是concreteProduct。可以看到在Application类(creator)中新增了一个成员数据结构docs,用来专门收集所有经过application实例化的对象,这样的操作可以有很多种,根据的实际需求而定,实现的地方也可以是在creator的父类也可以延迟到子类。不管怎样,这类的业务逻辑都可以被封装到creator中,而不用暴露给客户。对于的这类的需求都被封装到了creator,而creator可变的理由就只有一个,关于业务逻辑的需求(单一职责原则)。比起把这些业务逻辑交给客户来做,我们说软件的可维护性变高了。

    值得一提的是这类业务逻辑的封装恰恰是生成器模式(BUILDER)想达到的,不过这两个模式各有各的侧重点,生成器模式(BUILDER)强调的是生成product对象的策略,而工程模式(FACTORY METHOD)在这里强调的是一个新的抽象,这个新的抽象可以有不同的实现。稍后我们将会讲解生成器模式(BUILDER)的作用。

    

  2. 提供了一个新的类层次。

    正如书上所列举的第二个例子来说(如下图),Figure把一部分关于它的操作委托给了Manipulator类,这里的Figure类是creator,用户通过获取Figure类获取到其对应的Manipulator对象,既是对应的product对象。这样客户获取了一个非常容易理解的结构,对于一个特定的figure子类的对象,总是可以通过方法CreateManipulator获取到对应的Manipulator。要是你理解了这个设计的优势,是不是会顿悟原来工程模式(FACTORY METHOD)的用处是如此广泛,很多地方我们都不自觉的在使用的这个设计模式。只是我们没来得及归纳总结而已。这样的设计好处是显而易见的,更容易被人理解,同时它也遵循了开闭原则。你的设计在不知不觉间变得更优雅了。

    

   接下来我们讨论一下一个被称为简单工厂模式的实现,所谓的简单工厂模式就是只有creator不再是一个抽象类,而是一个能被实例化的具体类。在实现中会往Create中加入参数,根据数据的不同来生成不同的product对象。类似于下图。这个技巧是出现在gof的书中,同时它也是简单工程模式的组成部分,关于简单工程模式的详细信息读者可以自己百度,这里不再赘述。我们只谈这个简单工厂模式与gof书中提到的工厂模式(FACTORY METHOD)的异同点。

  a. 简单工厂模式只是在形式上与工厂模式类似。

    如果读者理解了上面关于工厂模式的解读,便会发现,gof描述的工厂模式强调的推迟对象的实例化到其子类,如果creator子类这个概念已经不存在了,似乎在生拉硬拽的让这两个模式的扯上关系有点太牵强了。可以说简单工厂模式借鉴了工厂模式的某些概念(如: creator)以及某些技巧(如:参数化创建),但是工厂模式的核心理念它并没有符合(推迟对象的实例化)。 

  b. 简单工厂模式可以很好符合数据驱动型设计。

    作为一个新晋设计模式,简单工厂模式也不是完全不可取的。我们考虑一种情况,如果设计中creator完全没有必要拓展,这个时候我们还会考虑新生成一个creator父类吗?同时简单工厂模式是可以通过输入参数来决定创建类型的,所有它对于那种数据驱动设计师非常合适的,通过不同的输入来决定相应的对象。 

    

  

 

    

posted @ 2017-03-06 15:46  远行的猴子  阅读(157)  评论(0编辑  收藏  举报