C++简单工厂模式详解
- 1.问题引入
- 2.编写代码思路的迭代
- 2.1 main函数主体内编写全部代码
- 2.2 修改上述问题后的main函数代码
- 2.3 引入面向对象后的代码
- 2.4 加上继承和多态后的代码
- 3.C++简单工厂代码
- 4.总结
- 4.1 简单工厂模式适用场景
- 4.2收获
1.问题引入
编写一个计算器程序代码,可使用任意一种面向对象语言编写。
2.编写代码思路的迭代
2.1 main函数主体内编写全部代码
在main函数主题写好了全部逻辑。包括两个运算数字的获取,中间运算符号的获取,通过对符号的if分支判断选取运算符参与运算数字的运算。这个时候出现的问题有:1.命名不规范。很多变量名都是A,B,C,不能通过名字知晓含义。2.if分支判断做了三次无用功,在这里可以选用switch。3.除法没有考虑除0判断,程序的健壮性不够。之后进行了第一次修改。
2.2 修改上述问题后的main函数代码
修改上诉问题后代码是没问题的,但是问题是不符合出题人心意。当前代码由于全部都在main函数里面,程序不容易维护,不容易拓展,不容易复用,不够灵活。
软件可维护性指的是维护人员对该软件进行维护的难易程度,具体包括理解、改正、改动和改进该软件的难易程度。
软件的可扩展性表现为基础设置不需要经常变更,应用之间较少依赖或耦合,可以对需求变更快速响应。
软件复用是使用已有的软件组件去实现或更新软件系统的过程。
软件开发中的灵活性通常是指管理方法和开发方法的灵活性,更细微的范围内则是指编码的灵活性。如果在解决某一问题时具备了多种可选择的方法,则可以认为开发过程拥有灵活性。
故接下来进行第二次修改。
2.3 引入面向对象后的代码
代码分为两部分,一部分是关于operation类的编写,包含了两个成员变量及计算的成员方法。另一个部分是主函数的编写。这样的好处是实现了业务和界面的分离。缺点是这里只用了封装,没有用到面向对象中的继承和多态。假如要新加一个开根号的运算(假设这里它只有加减乘除的运算),那么需要拿到所有方法代码再进行修改,但其实感觉上而言都是奇怪的操作,因为只想新加一个功能却需要拿到所有功能的代码才能进行添加。其实归根结底就是耦合度太高。
耦合度是某模块(类)与其它模块(类)之间的关联、感知和依赖的程度,是衡量代码独立性的一个指标,也是软件工程设计及编码质量评价的一个标准。
故接下来进行第三次修改。
2.4 加上继承和多态后的代码
在上一步,operation是作为主类,但是由于耦合度太高,所以做进一步耦合度的降低,采用继承和多态。所以有关于计算的四个类operationAdd、operationSub、operationMul、operationDiv继承operation,并且在operation中有虚方法getResult,子类里面都对该方法进行重写,从而实现多态。
那么其实就剩一个问题:就是实例化对象,比如增加开根号运算,那么我们应该考虑用一个类单独去制造出对象,这就是简单工厂模式。
3.C++简单工厂代码
//simpleFactory.h
#ifndef _SimpleFactory_H_
#define _SimpleFactory_H_
#include <iostream>
#include <exception>
#include <string>
using namespace std;
class Operation{
protected:
double _numberA = 0;
double _numberB = 0;
public:
Operation(){}
Operation(double a, double b){
_numberA = a;
_numberB = b;
}
Operation &operator=(Operation &p){
_numberA = p.getNumberA();
_numberB = p.getNumberB();
}
double getNumberA(){
return _numberA;
}
void setNumberA(double value){
_numberA = value;
}
double getNumberB(){
return _numberB;
}
void setNumberB(double value){
_numberB = value;
}
virtual double GetResult(){
return 0;
}
};
class OperationAdd:public Operation{
double GetResult(){
double result = 0;
result = _numberA + _numberB;
return result;
}
};
class OperationSub:public Operation{
double GetResult(){
double result = 0;
result = _numberA - _numberB;
return result;
}
};
class OperationMul:public Operation{
double GetResult(){
double result = 0;
result = _numberA * _numberB;
return result;
}
};
class OperationDiv:public Operation{
double GetResult(){
double result = 0;
try{
result = _numberA / _numberB;
}catch(exception &){
cout << "发生除0异常" << endl;
}
return result;
}
};
class OperationFactory{
public:
static Operation* createOperation(char operate){
Operation* oper;
switch (operate){
case '+':
oper = new OperationAdd();
break;
case '-':
oper = new OperationSub();
break;
case '*':
oper = new OperationMul();
break;
case '/':
oper = new OperationDiv();
break;
}
return oper;
}
};
#endif //_SimpleFactory_H_
//simpleFactory.cpp
#include "simpleFactory.h"
int main(){
Operation* oper;
oper = OperationFactory::createOperation('+');
oper->setNumberA(1);
oper->setNumberB(2);
double result = oper->GetResult();
std::cout << "Result: " << result << std::endl;
return 0;
}
//CSDN@Credic1017
4.总结
4.1 简单工厂模式适用场景
可以发现,简单工厂类是制造运算类的对象的,并且只需要传递关键参数给简单工厂类的方法(通常为静态方法),就可以创造出相应的对象出来。
故简单工厂适用于工厂类负责创建的对象较少的场景,且客户端只需要传入工厂类的参数,对于如何创建对象不需要关心。
4.2收获
1.可以通过封装、继承、多态把程序的耦合度降低。
2.可以通过设计模式使程序变得更加灵活,易于修改,并且易于复用。
3.简单工厂模式适用创建对象少的情况,需要传参来指定需要的对象(产品)。
参考:《大话设计模式》