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
#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";
}
#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
#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;
}
#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;
}
#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
请按任意键继续. . .
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
请按任意键继续. . .