工厂模式是为了解耦,将对象的创建和使用分离开。在客户端使用对象时,只需要知道对象的名称即可用一个共同接口来使用,而具体的创建过程对使用者屏蔽,所有对象的创建过程都由工厂来统一管理。
工厂模式分为三种:①简单工厂模式 ②工厂方法模式 ③抽象工厂模式; 本文介绍前两种。
①简单工厂模式只需要建一个工厂类,在该类中进行判断和对象创建。当需要增加新类型对象时,只需新增对应类,并修改工厂类即可。
②工厂方法模式除了建一个工厂抽象类之外,还需要对每个类型的对象都建一个工厂子类,在其中进行对象创建,即将对象的实例化延迟到工厂的子类。 当需要增加新类型对象时,需新增对应的类,并新增对应的工厂子类。
举个栗子,客户端需要对两个数进行加减乘除,代码如下:(只写了加和除,其他同理)
①简单工厂模式和②工厂方法模式都需要先对所有对象进行定义:建立抽象类Operation,其中获取计算结果的方法getResult()声明成一个纯虚函数,交给不同子类去进行不同的实现。
#include <iostream>
class Operation
{
protected:
double num1 = 0;
double num2 = 0;
public:
void setnum1(double x) { num1 = x; }
void setnum2(double x) { num2 = x; }
virtual double getResult() = 0;
};
class Add : public Operation
{
double getResult() override
{
return num1 + num2;
}
};
class Div : public Operation
{
double getResult() override
{
if (num2 == 0)
{
std::cout << "divide by zero" << std::endl;
std::abort();
}
else return num1 / num2;
}
};
对于①简单工厂模式,在工厂类OperationFactory中创建一个唯一的方法createOperate(),它能根据传入的string的类型来创建并返回不同的对象。 在main函数中,先建立工厂实例,再调用createOperate方法并传入所需的操作符,该方法就会返回一个与操作符对应的对象。
class OperationFactory
{
public:
Operation * createOperate(std::string op)
{
if (op == "+") return new Add;
else if (op == "/") return new Div;
else return nullptr;
}
};
int main()
{
OperationFactory opfac;
Operation* op = opfac.createOperate("/"); //需要不同对象时只用改这一句
op->setnum1(1.5);
op->setnum2(3.2);
std::cout << op->getResult() << std::endl;
return 0;
}
其UML类图如下:
对于②工厂方法模式,在工厂类OperationFactory中创建一个纯虚函数createOperate(),然后再派生多个工厂子类,用于创建不同对象。
class OperationFactory
{
public:
virtual Operation* createOperate() = 0;
};
class AddFactory : public OperationFactory
{
Operation* createOperate() override
{
return new Add;
}
};
class DivFactory : public OperationFactory
{
Operation* createOperate() override
{
return new Div;
}
};
int main()
{
OperationFactory* opfac = new AddFactory; //需要不同对象时只用改这一句
Operation* op = opfac->createOperate();
op->setnum1(1.5);
op->setnum2(3.2);
std::cout << op->getResult() << std::endl;
return 0;
}
其UML类图如下: