工厂方法模式(Factory Method)
概念
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。
模式结构
简单工厂模式对比
先回到简单工厂模式中的计算器的例子中,如果我们需要增加新的计算方法,我们需要新增Operator子类,并且在工厂方法中加入Case语句来判断。这显然违背了开放-封闭原则。
因此工厂方法模式根据依赖倒转原则,把工厂类抽象出一个接口,这个接口只有一个方法,就是创建抽象产品的工厂方法。然后所有的要生产具体类的工厂就去实现这个接口,这样,一个简单工厂模式的工厂类变成了一个工厂抽象接口和多个具体生产对象的工厂。
如下图所示:
模式实例与解析
#include <string>
#include <iostream>
using namespace std;
class LeiFeng
{
public:
virtual void Sweep()
{
cout << "LeiFeng sweep" << endl;
}
};
//学雷锋的学生,对应于ConcreteProduct
class Student : public LeiFeng
{
public:
virtual void Sweep()
{
cout << "Student sweep" << endl;
}
};
//学雷锋的志愿者,对应于ConcreteProduct
class Volunteer : public LeiFeng
{
public:
virtual void Sweep()
{
cout << "Volunteer sweep" << endl;
}
};
//工厂抽象基类 Creator
class LeiFengFactory
{
public:
virtual LeiFeng * CreateLeiFeng()
{
return new LeiFeng();
}
};
//工厂具体类
class StudentFactory : public LeiFengFactory
{
public:
virtual LeiFeng * CreateLeiFeng()
{
return new Student();
}
};
//工厂具体类
class VolunteerFactory : public LeiFengFactory
{
public:
virtual LeiFeng* CreateLeiFeng()
{
return new Volunteer();
}
};
int main()
{
LeiFengFactory * factory = new LeiFengFactory();
LeiFeng * student = new Student();
LeiFeng * volunteer = new Volunteer();
student->Sweep();
volunteer->Sweep();
delete factory;
delete student;
delete volunteer;
return 0;
}
判断移到客户端实现,添加新功能就不用修改原来的类,直接修改客户端即可。
优点
修正了简单工厂模式中不遵守开放-封闭原则。工厂方法模式把选择判断移到了客户端去实现,如果想添加新功能就不用修改原来的类,直接修改客户端即可。
适用性:
在下列情况下可以使用Factory Method模式:
- 当一个类不知道它所必须创建的对象的类的时候
- 当一个类希望由它的子类来指定它所创建的对象的时候
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。