● 简单工厂模式解释: 简单工厂模式(Simple Factory Pattern)属于类的创新型模式,又叫静态工厂方法模式(Static FactoryMethod Pattern),是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
(1)抽象(Product)产品角色:简单工厂模式所创建的所有对象的父类,注意:这里的父类可以是接口也可以是抽象类,它负责描述所有实例所共有的公共接口。
(2)具体产品(Concrete Product)角色:简单工厂所创建的具体实例对象,这些具体的产品往往都拥有共同的父类。
(3)工厂角色(Creator):这是简单工厂模式的核心,由它负责创建所有的类的内部逻辑。当然工厂类必须能够被外界调用,创建所需要的产品对象。
● 对于工厂模式,具体上可以分为三类:
简单工厂模式;
工厂方法模式;
抽象工厂模式。
工厂模式有一种非常形象的描述,建立对象的类就如一个工厂,而需要被建立的对象就是一个个产品;在工厂中加工产品,使用产品的人,不用在乎产品是如何生产出来的。从软件开发的角度来说,这样就有效的降低了模块之间的耦合。
对于上面的三种工厂模式,从上到下逐步抽象,并且更具一般性。而这篇博文主要讲的是简单工厂模式,后两种会在之后的博文中接着总结。
简单工厂模式深入分析:
简单工厂模式解决的问题是如何去实例化一个合适的对象。
简单工厂模式的核心思想就是:有一个专门的类来负责创建实例的过程。
具体来说,把产品看着是一系列的类的集合,这些类是由某个抽象类或者接口派生出来的一个对象树。而工厂类用来产生一个合适的对象来满足客户的要求。
如果简单工厂模式所涉及到的具体产品之间没有共同的逻辑,那么我们就可以使用接口来扮演抽象产品的角色;
如果具体产品之间有功能的逻辑,我们就必须把这些共同的东西提取出来,放在一个抽象类中,然后让具体产品继承抽象类。为实现更好复用的目的,共同的东西总是应该抽象出来的。
ProductA、ProductB和ProductC继承自Product抽象类,Show方法是不同产品的自描述;Factory依赖于ProductA、ProductB和ProductC,Factory根据不同的条件 创建不同的Product**对象**。
适用场合
● 在程序中,需要创建的对象很多,导致对象的new操作多且杂时,需要使用简单工厂模式;
● 由于对象的创建*过程是我们不需要去关心的,而我们注重的是对象的实际操作,所以,我们需要分离对象的创建和操作两部分,如此,方便后期的程序扩展和维护。*
代码实现为:
#include<iostream>
using namespace std;
class Operation //抽象运算类
{
public:
double getA()
{
return m_numberA;
}
void setA(double value)
{
m_numberA = value;
}
double getB()
{
return m_numberB;
}
void setB(double value)
{
m_numberB = value;
}
virtual double getResult()
{
double result = 0;
return result;
}
protected:
double m_numberA = 0;
double m_numberB = 0;
};
class OperationAdd : public Operation //加法类,继承运算类
{
public:
double getResult()
{
double result = m_numberA + m_numberB;
return result;
}
};
class OperationSub : public Operation //减法类,继承运算类
{
public:
double getResult()
{
double result = m_numberA - m_numberB;
return result;
}
};
class OperationMul : public Operation //乘法类,继承运算类
{
public:
double getResult()
{
double result = m_numberA * m_numberB;
return result;
}
};
class OperationDiv : public Operation //乘法类,继承运算类
{
public:
double getResult()
{
double result = 0;
if (m_numberB != 0)
{
result = m_numberA / m_numberB;
}
else
{
return -1;
}
return result;
}
};
class OperationFactory //工厂类
{
public:
Operation *createOperation(char type)
{
Operation *operation = nullptr;
switch (type)
{
case '+':
operation = new OperationAdd;
break;
case '-':
operation = new OperationSub;
break;
case '*':
operation = new OperationMul;
break;
case '/':
operation = new OperationDiv;
break;
}
return operation;
}
};
int main()
{
while (true)
{
cout << "\n请输入第一个数进行计算:";
double strNumberA;
cin >> strNumberA;
cout << "\n请先输入四则运算符号,进行相应的运算(+、-、*、/):\n" << endl;
char SignOfOperation = ' ';
while (cin >> SignOfOperation)
{
if (SignOfOperation == '+' || SignOfOperation == '-' || SignOfOperation == '*' || SignOfOperation == '/')
{
break;
}
else
{
cout << "请输入正确运算符号,否则无法进行计算,请重新输入:";
continue;
}
}
cout << "请输入第二个数进行计算:";
double strNumberB;
cin >> strNumberB;
{
cout << "\n*************************************************************" << endl
<< "******************** 计算器基本功能展示. **********************" << endl
<< "*****************************************************************" << endl
<< "******************** 选择1——进行加法. **********************" << endl
<< "******************** 选择2——进行减法. **********************" << endl
<< "******************** 选择3——进行乘法. **********************" << endl
<< "******************** 选择4——进行除法. **********************" << endl
<< "******************** 选择5——清屏. **********************" << endl
<< "*****************************************************************" << endl;
}
cout << "\n******************** 请输入你想要使用的计算器的序号 ***************" << endl;
cout << "请输入你的选择:";
int userChoice(0);
if (cin >> userChoice && userChoice == 0)
{
cout << "程序已退出,感谢您的使用!" << "\n" << endl;
break;
}
Operation* oper = nullptr;
OperationFactory of; //创建一个运算工厂类对象
switch (userChoice)
{
case 1:
oper = of.createOperation(SignOfOperation);
oper->setA(strNumberA);
oper->setB(strNumberB);
cout << strNumberA << "+" << strNumberB << "=" << (oper->getResult()) << endl;
break;
case 2:
oper = of.createOperation(SignOfOperation);
oper->setA(strNumberA);
oper->setB(strNumberB);
cout << strNumberA << "-" << strNumberB << "=" << (oper->getResult()) << endl;
break;
case 3:
oper = of.createOperation(SignOfOperation);
oper->setA(strNumberA);
oper->setB(strNumberB);
cout << strNumberA << "*" << strNumberB << "=" << (oper->getResult()) << endl;
break;
case 4:
{
oper = of.createOperation(SignOfOperation);
oper->setA(strNumberA);
oper->setB(strNumberB);
if (double temp = oper->getResult())
{
cout << strNumberA << "/" << strNumberB << "=" << temp << endl;
}
else
{
cout << "错误,除数不能为0!" << endl;
}
break;
}
case 5:
system("cls");
cout << "屏幕已经清屏,可以重新输入!" << "\n" << endl;
break;
default:
cout << "输入的序号不正确,请重新输入!" << "\n" << endl;
}
delete oper;
oper = nullptr;
}
system("pause");
return 0;
}
简单工厂模式的优缺点分析:
● 优点: 工厂类是整个模式的关键所在。它包含必要的判断逻辑,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象。 用户在使用时可以直接根据工厂类去创建 所需的实例,而无需了解这些对象是如何创建以及如何组织的。有利于整个软件体系结构的优化。
● 缺点:由于工厂类集中了所有实例的创建逻辑,这就直接导致一旦这个工厂出了问题,所有的客户端都会受到牵连;而且由于简单工厂模式的产品是基于一个共同的抽象类或者接口,这样一来,一但产品的种类增加的时候,即有不同的产品接口或者抽象类的时候,工厂类就需要判断何时创建何种种类的产品,这就和创建何种种类产品的产品相互混淆在了一起,违背了单一职责,导致系统丧失灵活性和可维护性。
而且更重要的是: 简单工厂模式违背了“开放封闭原则”,就是违背了“系统对扩展开放,对修改关闭”的原则,因为当我们新增加一个产品的时候必须修改工厂类,相应的工厂类就需要重新编译一遍。
总结一下: 简单工厂模式分离产品的创建者和消费者,有利于软件系统结构的优化;但是由于一切逻辑都集中在一个工厂类中,导致了没有很高的内聚性,同时也违背了“开放封闭原则”。
另外,简单工厂模式的方法一般都是静态的,而静态工厂方法是无法让子类继承的,因此,简单工厂模式无法形成基于基类的继承树结构。
本章完,但有待更新和学习