设计模式四:Factory method工厂方法——对象创建型模式

Factory method工厂方法——对象创建型模式


1.意图
定义一个用于创建对象的接口,让子类决定实例化哪个类。使一个类的实例化延迟到其子类


2.别名
虚构造器(virtual constructor)


3动机
框架使用抽象类定义和维护对象之间的关系。这些对象的创建通常也由框架负责。
一个框架中有两个抽象类Application和Document,因为被实例化的Document子类和特定应用相关,所以Application不知道哪个Document类将被实例化。仅知道一个文档何时被创建,但是不知道哪一种Document被创建,就产生了一个问题:框架必须实例化类,但是他只知道不可被实例化的抽象类。
Application的子类重新定义父类的抽象操作CreateDocument以返回适当的Document子类对象。一旦一个Application的子类被实例化之后就可以实例化与应用程序相关的文档而不需要知道产生这些文档的类。
CreateDocument就是一个工厂方法,因为他负责生产一个对象。


4.适用性
当一个类不知道他所必须创建的对象的类的时候
当一个类希望由他的子类来指定他所创建的对象的时候
当类将创建对象的职责委托给多个帮助子类中的某一个,并且希望将哪一个帮助子类是代理者这一信息局部化的时候

5.结构

http://www.cnblogs.com/yuyijq/archive/2007/10/12/921966.html

参考一下别人画的图


6.参与者
product
定义工厂方法所创建的对象接口
concreteProduct
实现product接口
creator
声明工厂方法,该方法返回一个product类型的对象
creator也可以定义一个工厂方法的缺省实现,返回一个concreteProduct对象
可以调用工厂方法以创建一个product对象
concreteCreator
重定义工厂方法以返回一个concreteProduct实例

 


7.协作
creator依赖于它的子类来定义工厂方法,所以返回一个适当的concreteCreator实例。

 

8.效果
工厂方法不再将与特定应用有关的类绑定到你的代码中。
缺点:客户可能仅仅为了创建一个特定的ConcreteProduct对象就不得不创建Creator的子类。
工厂模式的另外两种效果
1)为子类提供挂钩(hook)
用工厂方法在一个类的内部创建对象通常比直接创建对象更加灵活。
2)连接平行的类层次
当一个类将一些指责委托给一个独立的类的时候,就产生了平行类层次。

 

9.实现
1)主要有两种不同的情况
第一种:creator类是抽象类并且不提供他所声明的工厂方法的实现。
    需要子类来定义实现,因为没有缺省的实现,避免了不得不实例化不可预见类的问题。
第二种:creator是一个具体的类而且为工厂方法提供一个缺省的实现。
    需要灵活性才使用工厂方法,“用一个独立的操作创建对象,这样子类才能重新定义他们的创建方式”
2)参数化工厂方法
采用一个标示要被创建的对象种类的参数,使工厂方法可以创建多种产品。工厂方法创建的所有对象将共享product接口。
3)特定语言中的问题
C++中的工厂方法都是虚函数并且通常是纯虚函数。一定注意在creator的构造器中不要调用工厂方法——在ConcreteCreator中该工厂方法还不可以用
4)使用模板以避免创造子类
为了避免仅仅为了创建适当的Product对象而迫使你创建Creator子类,另一个解决方案是提供Creator一个模板类
5)使用命名约定


10.代码示例

#include<iostream>
#include<string>
using namespace std;

class car
{
    public: 
    string getName()
    {
        return name;
    }
    void setName(string str)
    {
        name = str;
    }
    private:
    string name;
};
class BMW:public car
{
    public:
    BMW(string s="BMW car")
    {
        setName(s);
    }
};

class QQ:public car
{
    public:
    QQ(string s="QQ car")
    {
        setName(s);
    }
};
class AbstractFactory
{
    public:
    virtual car getCar(){};
};

class BMWFactory:public AbstractFactory
{
    public:
    car getCar()
    {
        BMW b("a new BMW car");
        return b; 
    }
};
class QQFactory:public AbstractFactory
{
    public:
    car getCar()
    {
        QQ q("a new qqqqqqq~~~~");
        return q;
    }
};
int main()
{
    AbstractFactory *abf = new QQFactory();
    car c = abf->getCar();
    cout<<c.getName()<<endl;
    
    AbstractFactory *abf2 = new BMWFactory();
    car cb = abf2->getCar();
    cout<<cb.getName()<<endl;
}

 


11.相关模式
AbstractFactory通常用工厂方法来实现
工厂方法通常在TemplateMethod中被调用
Prototype不需要创建Creator的子类,但是他们通常要求一个针对Product类的Initialize操作。
Creator使用Initialize来初始化对象,而FactoryMethod不需要这样的操作。

posted @ 2012-05-18 20:15  w0w0  阅读(219)  评论(0)    收藏  举报