目录
为什么要使用简单工厂模式?
answer:保证代码的可复用性,使各个子类完全分离,避免更高一层的代码去改底层的代码。
怎样实现简单工厂模式?
answer:专门定义一个类来创建其他类的实例,被实例的类一般都有相同的父类。简单工厂的实质是根据工厂方法传入的参数来决定要实例化哪一个类。
接下来分析一下简单工厂模式的UML图,以我们将要实现的计算器为例。
可知:加法类、减法类、乘法类、除法类都是相同等级的类。我们可以专门定义一个运算类(工厂类)来实例化各个类。
简单工厂模式使用实例(计算器)
# include<iostream>
using namespace std;
# include<string>
//定义一个基类
class Operation
{
public:
void setA()
{
double num;
cout << "请输入第一个数:";
cin >> num;
numA = num;
}
double getA()
{
return numA;
}
void setB()
{
double num;
cout << "请输入第一个数:";
cin >> num;
numB = num;
}
double getB()
{
return numB;
}
//虚函数实现动态绑定
virtual double getResult()
{
return 0.0;
}
private:
double numA;
double numB;
};
//通过继承基类获得四个产品
class OperationAdd : public Operation
{
public:
virtual double getResult()
{
return (Operation::getA() + Operation::getB());
}
};
class OperationSub : public Operation
{
public:
virtual double getResult()
{
return (Operation::getA() - Operation::getB());
}
};
class OperationMuti : public Operation
{
public:
virtual double getResult()
{
return (Operation::getA() *Operation::getB());
}
};
class OperationDiv : public Operation
{
public:
virtual double getResult()
{
try
{
int a = 0;
if (Operation::getB() == 0.0)
{
throw a;
}
}
catch (int)
{
cout << "除数不能为!!!" << endl;
}
return (Operation::getA() + Operation::getB());
}
};
//工厂类 可以在工厂类中实现产品的实例化
class OperationFactory
{
public:
Operation* createOperate(char str)
{
//实现了多种产品的实例化。
switch (str)
{
case '+':
oper = new OperationAdd();
break;
case '-':
oper = new OperationSub();
break;
case '*':
oper = new OperationMuti();
break;
case '/':
oper = new OperationDiv();
break;
}
return oper;
}
private:
//不能用对象直接访问虚方法,这样是静态绑定,虚函数就会失去作用。必须运用引用或者指针才能实现动态绑定。
Operation *oper;
};
int main()
{
//实例化一个工厂
OperationFactory op;
//用一个产品的基类对象来接受产品的实例化
Operation *oper = op.createOperate('+');
//进行相应的操作
oper->setA();
oper->setB();
cout << oper->getResult() << endl;
system("pause");
return 0;
}
这样就实现了一个简答工厂模式。
简单工厂模式的优缺点:
优点:提供了一个工厂类,动态的实例不同的对象,去除了对产品的依赖性。在需要别的类的时候,只需要在工厂类中加入其他对象的实例化方式就可以。适用于本身就很简单的系统。
缺点:虽然在工厂类可以实例化不同的对象,但在需要增加类的时候,必须修改工厂类中的源代码,在case语句里面加上新类的逻辑,这一点违反了开闭原则。在工厂方法和抽象工厂方法中,这一缺点将会得到解决。