定义
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法(Factory Method
)使一个类的实例化延迟到其子类。也叫虚构造器(Virtual Constructor
)
结构
理解
1. Product
是工厂方法生产产品的抽象基类。
2. Creator
是生产产品的工厂对象抽象基类。Creator
提供创建虚方法即工厂方法FactoryMeothod()
。FactoryMeothod()
由派生类(ConcreteCreator
)具体实现,生产对应的具体产品(ConcreteProduct
)。
3. ConcreteProduct
是继承Product
的具体产品。
4. ConcreteCreator
是生产对应具体产品(ConcreteProduct
)的具体工厂。它重新实现继承的工厂方法FactoryMeothod()
,生产具体产品。
要点
1.
工厂方法模式中,工厂和产品的基类和派生类是平行关系。抽象产品(Product
)对应层次是抽象工厂(Creator
)。在派生类层次,每个具体产品(ConcreteProduct
)对应一个具体工厂(ConcreteCreator
)。换句话说,每新增一个具体产品,就要新增一个对应的具体工厂。
2.
工厂方法的核心是FactoryMeothod()
,每个具体工厂都重新实现该接口,产生具体类对象。
3.
工厂方法分离客户端和具体类的实现。利用子类(即具体工厂),让子类来决定如何来生产一个具体产品。这样,客户端(即调用者)只需要知道这个类的抽象类型,由子类去和具体产品类打交道。
4.
工厂基类中的方法AnOperation()
,不是工厂方法,只是供具体工厂实现的公共接口(可以说是工厂对产品的使用行为)。但个人认为,工厂方法只是生产产品,公共接口的重点应该是产品,因此在产品基类里增加产品使用的公共接口更加实用。
5.
工厂方法模式的工厂(Creator
)若要全局唯一,可以结合单件(Singleton
)模式应用。
6.
关于简单工厂
(
也叫静态工厂
)
。工厂方法强调的是“让子类决定实例化什么样的对象”,因为子类知道它们要使用的特定产品。如果我们将Creator
和ConcreteCreator
的角色合一,并且将工厂方法FactoryMeothod()
静态化,那么就退化成了简单工厂模式。
应用
1.
工厂方法应用场景:
当一个类不知道它所必须创建的对象的类的时候。
当一个类希望由它的子类来指定它所创建的对象的时候。
当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。(往往放在抽象产品侧)
2. Loki
库中对工厂方法有一个比较完美的实现,结合了函数对象(Functor
),可制定产品创建方法。可参见:
http://loki-lib.sourceforge.net/index.php?n=Pattern.FactoryMethod
3.
源码中的应用
COSProduct
是产品基类。并且有产品的公共使用接口。
COSCreator
是工厂基类。模式结构中的产品使用行为接口AnOperaion
并没有出现在工厂基类接口中,放在了产品侧(Start
接口)。
具体工厂可以通过继承COSCreator
实现,有多少个具体工厂,就要有多少个具体工厂类。通过C++
模板可以避免创建多个具体工厂(模板类CConcreteCreator
)。
源码
#include
<iostream>
#include
<string>
using
namespace std;
///
产品
class
COSProduct
{
public
:
virtual ~COSProduct(){};
//
产品的公共接口。相当于
AnOperation
virtual void Start() = 0;
};
class
CWindowsProduct : public COSProduct
{
public
:
virtual void Start()
{
cout << "Windows start." << endl;
}
};
class
CLinuxProduct : public COSProduct
{
public
:
virtual void Start()
{
cout << "Linux start." << endl;
}
};
///
工厂基类
class
COSCreator
{
public
:
~COSCreator(){};
//
工厂方法。生产产品
virtual COSProduct* Create() = 0;
};
///
具体工厂
class
CWindowsCreator : public COSCreator
{
public
:
virtual COSProduct* Create()
{
cout << "Create windows…" << endl;
return new CWindowsProduct;
};
};
class
CLinuxCreator : public COSCreator
{
public
:
virtual COSProduct* Create()
{
cout << "Create linux…" << endl;
return new CLinuxProduct;
};
};
/
另一种具体工厂:使用模板避免创建多个具体工厂子类
template
<typename T>
class
CConcreteCreator : public COSCreator
{
public
:
CConcreteCreator(const string strProductType) : m_strProductType(strProductType)
{};
virtual COSProduct* Create()
{
cout << "ConcreteCreator. product type: " << m_strProductType << endl;
return new T;
};
protected
:
string m_strProductType;
};
int
main()
{
COSCreator* pCreator = NULL;
COSProduct *pProduct = NULL;
pCreator = new CWindowsCreator;
pProduct = pCreator->Create();
pProduct->Start();
delete pProduct;
delete pCreator;
pCreator = new CLinuxCreator;
pProduct = pCreator->Create();
pProduct->Start();
delete pProduct;
delete pCreator;
//
另一种实现具体工厂方式:使用模板避免创建子类
CConcreteCreator<CWindowsProduct> windowsCreator("windows");
pProduct = windowsCreator.Create();
pProduct->Start();
delete pProduct;
CConcreteCreator<CLinuxProduct> linuxCreator("linux");
pProduct = linuxCreator.Create();
pProduct->Start();
delete pProduct;
system("pause");
return 0;
}
输出:
Create windows…
Windows start.
Create linux…
Linux start.
ConcreteCreator. product type: windows
Windows start.
ConcreteCreator. product type: linux
Linux start.