工厂模式属于创建型模式,主要可分为三类,简单工厂、工厂方法、抽象工厂。工厂模式规定,无论是工厂函数,工厂类的成员函数,返回的对象都必须位于heap。
有三点需要特别注意:
堆对象
三种工厂模式都属于创建型模型,所创建的对象都位于堆内存中,需要手动释放其所占内存。
基类的虚析构函数
在Scott Meyers大师的
Effective C++
有专门一节论述将析构函数声明为虚析构函数的必要性。其中所举的范例即是工厂方法模式。当derived class 对象经由一个base class指针(工厂方法的create方法返回的恰是基类指针,因为它不确定创建的是哪个子类对象)删除,而该base class 带着一个non-virtual析构函数,其结果未有定义(undefined behavior)。UML类图
UML类图是把握设计模式的关键,如何将一段描述转换为UML类图,如何将UML类图转换为程序语言,是软件开发的一项基本能力。更详尽的内容请见
简单工厂模式
其主要特点是需要创建对象时,需要在工厂类中做判断(if
),根据不同的条件或者前提创建不同的对象。这也就造成了,当增加新的产品时,需要修改工厂类,也就是其增加其判断分支。
一家成产处理器核的厂家(对应着一个工厂类),能够生产两种类型的处理器核。简单工厂模式要求,客户需要什么样的处理器核,务必显式地告知工厂。
先看UML类图:
这里不妨简单做个说明,虚线表示的是依赖关系(dependency),即
SingleCoreA
类和
SingleCoreB
在
Factory
的类声明中会以成员函数的局部对象的形式出现,如果以成员变量的方式出现的话,就不叫依赖关系,而是关联关系了(association)。三角箭头表示的是继承关系,在UML的术语中叫泛化关系(generation)。
enum CORETYPE {COREA, COREB};
class SingleCore
{
public:
virtual void show() = 0;
virtual ~SingleCore();
}
class SingleCoreA : public SingleCore
{
public:
void show()
{ std::cout << "SingleCoreA::show()" << std::endl;}
}
class SingleCoreB : public SingleCore
{
public:
void show()
{ std::cout << "SingleCoreB::show()" << std::endl;}
}
class Facotry
{
public:
SingleCore* createSingleCore(CORETYPE type)
{
// 返回基类指针,构成一种依赖关系,dependency
if (type == COREA)
return new SingleCoreA;
else if (type == COREB)
return new SingleCoreB;
else
return NULL;
}
}
int main(int, char**)
{
Factory fact;
SingleCore* core = fact.cretaSingleCore(COREB);
//
delete core; // heap object
return 0;
}
工厂方法模式
因为简单工厂将所有欲创建的子类集合在了一起,耦合度较高。当要增加新的产品类型时,需要修改工厂类,违反了开闭原则,即对扩展开放,对修改关闭,或者说,软件实体(类、模块、函数)可以扩展,但是不可修改。工厂方法(Factory Method),将创建的动作分配给不同的工厂子类,一个工厂子类对应于一个产品的创建。Factory Method使一个类的实例化的动作延迟到其子类。
class SIngleCore
{
public:
virtual void show() = 0;
}
class SingleCoreA :public SingleCore
{
public:
void show() { std::cout << "SingleCore::show()" << std::endl;}
}
class SingleCoreB: public SingleCore
{
public:
void show() { std::cout << "SingleCoreB::show()" << std::endl;}
}
class Factory
{
public:
virtual SingleCore* createSingleCore() = 0;
}
class FactoryA : public Factory
{
public:
SingleCore* createSingleCore()
{ return new SingleCoreA;} // 工厂子类FactoryA对应于产品子类SingleCoreA的创建
}
class FactoryB : public Factory
{
public:
SingleCore* createSingleCore()
{ return new SingleCoreB;} // 工厂子类FactoryB对应于产品子类SingleCoreB的创建
}
int main(int, char**)
{
SingleCore* core;
FactoryA fa;
FactoryB fb;
core = fa.createSingleCore();
core->show(); // 调用SingleCoreA的show()方法
delete core;
core = fb.createSingleCore();
core->show(); // 调用SingleCoreB的show()方法
de
return 0;
}
工厂方法模式也有自己的缺点,每增加一个商品,虽然不像简单工厂,需要修改工厂类,而是需要增加一个对象的工厂。如果商品的种类有很多时,例如iPhone4S,iPhone5,iPhone5S,…,等等一系列的产品的时候。在C++的实现中,就需要定义一个个的工厂类。显然这与简单工厂模式相比,需要更多的类定义。
抽象工厂模式
抽象工厂模式,它的定义提供一个创建一系列相关或相互依赖对象的接口,而无需指定具体的类。(不知道这样理解对不对)
class SingleCore
{
public:
virtual void show() = 0;
}
class SingleCoreA:public SingleCore
{
public:
void show()
{ std::cout << "SingleCoreA::show()" << std::endl;}
}
class SingleCoreB:public SingleCore
{
public:
void show()
{ std::cout << "SingleCoreB::show()" << std::endl;}
}
class MutliCore
{
public:
virtual void show() = 0;
}
class MultiCoreA:public MultiCore
{
public:
void show()
{ std::cout << "MultiCoreA::show()" << std::endl;}
}
class MultiCoreB:public MultiCore
{
public:
void show()
{ std::cout << "MultiCoreB::show()" << std::endl;}
}
class CoreFactory
{
public:
virtual SingleCore* createSingleCore();
virtual MultiCore* createMultiCore();
}
class FactoryA :public CoreFactory
{
public:
SingleCore* createSingleCore()
{ return new SingleCoreA;}
MultiCore* createSingleCore()
{ return new MultiCoreA;}
}
class FactoryB :public CoreFactory
{
public:
SingleCore* createSingleCore()
{ return new SingleCoreB;}
MultiCore* createMultiCore()
{ return new MultiCoreB;}
}
int main(int, char**)
{
MultiCore* mcore;
FactoryA fa;
FactoryB fb;
mcore = fa.createMultiCore();
mcore->show();
mcore = fb.createMultiCore();
mcore->show();
return 0;
}