现在的位置: 首页 > 综合 > 正文

设计模式: 工厂方法模式(Factory Method)

2012年05月05日 ⁄ 综合 ⁄ 共 3282字 ⁄ 字号 评论关闭
文章目录
Simple Factory模式经常在系统开发中用到,但是这并不是 Factory 模式的最大威力所在(因为这可以通过其他方式解决这个问题)。Factory模式不单是提供了创建对象的接口,其最重要的是延迟了子类的实例化(第二个问题),以下是这种情况的一个 Factory 的结构示意图:
Factory模式的应用并不是只是为了封装对象的创建,而是要把对象的创建放到子类中实现:Factory 中只是提供了对象创建的接口,其实现将放在 Factory 的子类ConcreteFactory中进行.

讨论

Factory 模式在实际开发中应用非常广泛,面向对象的系统经常面临着对象创建问题:
要创建的类实在是太多了。而 Factory 提供的创建对象的接口封装(第一个功能),以及其将类的实例化推迟到子类(第二个功能)都部分地解决了实际问题。Factory模式也带来至少以下两个问题:
1)如果为每一个具体的 ConcreteProduct 类的实例化提供一个函数体,那么我们可能不得不在系统中添加了一个方法来处理这个新建的 ConcreteProduct,这样 Factory 的接口永远就不肯能封闭(Close)。当然我们可以通过创建一个 Factory的子类来通过多态实现这一点,但是这也是以新建一个类作为代价的。
2)在实现中我们可以通过参数化工厂方法,即给 FactoryMethod()传递一个参数用以决定是创建具体哪一个具体的 Product。当然也可以通过模板化避免子类创建子类,其方法就是将具体 Product 类作为模板参数,实现起来也很简单。可以看出,Factory 模式对于对象的创建给予开发人员提供了很好的实现策略,但是Factory 模式仅仅局限于一类类(就是说 Product 是一类,有一个共同的基类),如果我们要为不同类的类提供一个对象创建的接口,那就要用 Abstract Factory了。
 

实现

// Plane.h
#ifndef __PLANE_H__
#define __PLANE_H__
#include <string>
class IPlane
{
public:
    void fly();
    virtual ~IPlane();
    virtual const char* name() = 0;
};
class CF10Plane: public IPlane
{
public:
    const char* name();
};
class CF11Plane: public IPlane
{
public:
    const char* name();
};
class CM10Plane: public IPlane
{
public:
    const char* name();
};
class CM11Plane: public IPlane
{
public:
    const char* name();
};
#endif
 
// Plane.cpp
#include "Plane.h"
void IPlane::fly()
{
    printf("My name is %s, i am flying\n",name());
}
IPlane::~IPlane()
{
}
const char* CF10Plane::name()
{
    return "F10";
}
const char* CF11Plane::name()
{
    return "F11";
}
const char* CM10Plane::name()
{
    return "M10";
}
const char* CM11Plane::name()
{
    return "M11";
}
 
// PlaneFactory.h
#ifndef __PLANEFACTORY_H__
#define __PLANEFACTORY_H__
class IPlane;
class IPlaneFactory
{
public:
    virtual ~IPlaneFactory();
    IPlane* BuildPlane(const char* szName);
private:
    virtual IPlane* CreatePlane(const char* szName) = 0;
};
class CFPlaneFactory:public IPlaneFactory
{
private:
    IPlane* CreatePlane(const char* szName);
};
class CMPlaneFactory:public IPlaneFactory
{
private:
    IPlane* CreatePlane(const char* szName);
};
#endif
 
// PlaneFactory.cpp
#include "PlaneFactory.h"
#include "Plane.h"
IPlaneFactory::~IPlaneFactory()
{
}
IPlane* IPlaneFactory::BuildPlane(const char* szName)
{
    IPlane* pPlane = CreatePlane(szName);
    if (pPlane)
    {
        printf("Build success,");
        pPlane->fly();
    }
    else
    {
        printf("Build failed,not exist %s\n",szName);
    }
    return pPlane;
}
IPlane* CFPlaneFactory::CreatePlane(const char* szName)
{
    IPlane* pPlane = NULL;
    if (strcmp(szName,"F10") == 0)
    {
        pPlane = new CF10Plane();
    }
    else if (strcmp(szName,"F11") == 0)
    {
        pPlane = new CF11Plane();
    }
    return pPlane;
}
IPlane* CMPlaneFactory::CreatePlane(const char* szName)
{
    IPlane* pPlane = NULL;
    if (strcmp(szName,"M10") == 0)
    {
        pPlane = new CM10Plane();
    }
    else if (strcmp(szName,"M11") == 0)
    {
        pPlane = new CM11Plane();
    }
    return pPlane;
}
 
// main.cpp
#include <iostream>
#include "Plane.h"
#include "PlaneFactory.h"
int main()
{
    CFPlaneFactory fPlaneFactory;
    fPlaneFactory.BuildPlane("F10");
    fPlaneFactory.BuildPlane("F11");
    fPlaneFactory.BuildPlane("F12");
    CMPlaneFactory mPlaneFactory;
    mPlaneFactory.BuildPlane("M10");
    mPlaneFactory.BuildPlane("M11");
    mPlaneFactory.BuildPlane("M12");
    return 0;
}
 
Build success,My name is F10, i am flying
Build success,My name is F11, i am flying
Build failed,not exist F12
Build success,My name is M10, i am flying
Build success,My name is M11, i am flying
Build failed,not exist M12
请按任意键继续. . .

抱歉!评论已关闭.