类创建型模式之工厂方法(Factory Method)

本小妞迷上赌 提交于 2020-02-04 07:16:05

类创建型模式之工厂方法(Factory Method)

一、创建型模式概述

    创建型模式(Creational Pattern)抽象了实例化过程,它们帮助一个系统独立于如何创建、组合和表示它的那些对象。

    创建型模式分为类的创建模式和对象的创建模式两种:

    类的创建模式:类的创建模式使用继承关系,把类的创建延迟到子类,从而封装了客户端将得到哪些具体类的信息,并且隐藏了这些类的实例是如何被创建和放在一起的。

对象的创建模式:对象的创建模式把对象的创建过程动态地委派给另一个对象,从而动态地决定客户端将得到哪些具体类的实例,以及这些类的实例是如何被创建和组合在一起的。

二、工厂方法介绍

(1)意图

    工厂方法(Factory Method)模式是类的创建模式,它通过定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到其子类。

(2)别名

工厂方法又称为虚构造器( Virtual Constructor)。

(3)动机

    如图中所示,Application的子类重定义Application的抽象操作CreateDocument以返回适当的Document子类对象,一旦一个Application子类实例化后,它就可以实例化与应用相关的文档,而无需知道这些文档的类,我们称CreateDocument是一个工厂方法,因为它负责“生产一个对象”。

在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不接触哪一个产品类被实例化这种细节。这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。在Factory Method模式中,工厂类与产品类往往具有平行的等级结构,它们之间一一对应。

(4)结构

(5)参与者

Product:定义工厂方法所创建的对象(即工厂的产品)的接口。

ConcreteProduct:实现Product接口的具体产品类。

Creator:声明工厂方法,该方法返回一个Product类型的对象。Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteProduct对象。可以通过调用Creator的工厂方法以创建一个Product对象。

ConcreteCreator:重定义工厂方法以返回一个ConcreteProduct实例。

(6)适用性

在下列情况下可以使用Factory Method模式:

    当一个类不知道它所必须创建的对象的类的时候。

    当一个类希望由它的子类来指定它所创建的对象的时候。

当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。

(7)效果

    工厂方法不再将与特定应用有关的类绑定到客户代码中。客户代码仅处理Product接口,因此它可以与何ConcreteProduct类一起使用。

    工厂方法的一个潜在缺点在于客户可能仅仅为了创建一个特定的ConcreteProduct对象,就不得不创建Creator的子类。

利用工厂方法可以连接平行的类层次。当一个类将它的一些职责委托给一个独立的类的时候,就产生了平行类层次(如下图)

(8)实现

    C++中的工厂方法都是虚函数,并且常常是纯虚函数。

Factory Method模式主要有两种不同的情况: 

    Creator是一个抽象类,不提供它所声明的工厂方法的实现。

    Creator是一个具体类,为工厂方法提供一个缺省的实现。

  参数化工厂方法

通过参数化使得一个工厂方法可以创建多种产品。在这种情况下工厂方法采用一个标识(如字符串)作为参数,表明要被创建的对象的种类,工厂方法创建的所有对象将共享Product接口。有时也称这种情况为简单工厂模式(Simple Factory)。在这种情况下的类结构图和代码例子如下:

class Creator

{

public:

 virtual Product* Create(ProductId);//抽象产品

}

Product* Creator::Create(ProductId id){

if(id==MINE) return new MyProduct;//具体产品

if(id==YOURS) return new YourProduct;

//repeat for remaining products...

return 0;

}

(9)然而我们要明确的是:在面向对象的编程中,对象的创建工作非常简单,对象的创建时机却很重要。Factory Method要解决的就是对象的创建时机问题,它提供了一种扩展的策略,很好地符合了开放封闭原则。

    面向对象的封装(Encapsulation)和分派(Delegation)告诉我们,尽量将长的代码分派“切割”成每段,将每段再“封装”起来(减少段和段之间偶合联系性),这样,就会将风险分散,以后如果需要修改,只要更改每段,不会再发生牵一动百的事情。

参考:

1、《设计模式》(中文版)

2、http://www.cnblogs.com/yuanermen/archive/2007/03/13/673723.html

3、http://www.jdon.com/designpatterns/designpattern_factory.htm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!