设计模式(1)-使用简单工厂优化代码

首先看一段程序,目的是完成一个计算器的计算,

面向过程的写法


#include "stdafx.h"
#include <string>
#include <iostream>
 
using namespace std;
 
int main(int argc, char* argv[])
{
 int strNumA,strNumB;
 int strOperator;
 cout<<"请输入数字A:\n";
 cin>>strNumA;
 cout<<"请选择运算符号(1,+,2,-,3,*,4,/):\n";
 cin>>strOperator;
 cout<<"请输入数字B:\n";
 cin>>strNumB;
 
 int strResult;
 switch(strOperator)
 {
 case OPERATOR_ADD:
 strResult = strNumA + strNumB;
 break;
 case OPERATOR_MINUS:
 strResult = strNumA - strNumB;
 break;
 case OPERATOR_MUTHL:
 strResult = strNumA * strNumB;
 break;
 case OPERATOR_DIV:
 if(strNumB!=0)
 strResult = strNumA / strNumB;
 else
 cout<<"您输入的有误,除数不能为0!"<<endl;
 break;
 default:
 cout<<"输入有错误!"<<endl;
 break;
 }
 cout<<"得到的结果是:"<<strResult;
 return 0;
}

这样出来的程序每次都需要修改,比如我要添加一个取平方根的操作,需要修改程序,如果在增加,还是继续修改。

面向对象和面向过程的对比就不用多说了吧,借用书上的一句话

通过继承封装和多态把程序的耦合度降低,使用设计模式使程序更灵活更加容易复用。

第一步 剥离业务,现在程序都是混在一起的,将业务剥离出来

创建类Operaton


class Operaton
{
public: 
 int getResult(int strNumA,int operFlag,int strNumB)
 {
 int result=0;
 switch(operFlag)
 {
 case OPERATOR_ADD:
 result = strNumA + strNumB;
 break;
 case OPERATOR_MINUS:
 result = strNumA - strNumB;
 break;
 case OPERATOR_MUTHL:
 result = strNumA * strNumB;
 break;
 case OPERATOR_DIV:
 if(strNumB!=0)
 result = strNumA / strNumB;
 else
 cout<<"您输入的有误,除数不能为0!"<<endl;
 break;
 default:
 cout<<"输入有错误!"<<endl;
 break;
 }
 return result;
 }
};

修改main函数

int main(int argc, char* argv[])
{
 int strNumA,strNumB;
 int strOperator;
 cout<<"请输入数字A:\n";
 cin>>strNumA;
 cout<<"请选择运算符号(1,+,2,-,3,*,4,/):\n";
 cin>>strOperator;
 cout<<"请输入数字B:\n";
 cin>>strNumB;
 
 int strResult = 0;
 Operaton *op = new Operaton;
 strResult = op->getResult(strNumA,strOperator,strNumB);
 cout<<"得到的结果是:"<<strResult;
 return 0;
}

这样实现了业务逻辑的分离,但是还是没解决刚才的问题,如果再添加操作或业务还需要再修改业务类文件。

第二步 使用简单工厂

工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。

看一下类图的描述

设计模式(1)-使用简单工厂优化代码

从而得到的几个文件Operaton.cpp,Operaton.h,OperatonAdd.cpp,OperatonAdd.h,OperatonSub.cpp,OperatonSub.h,OperatonMul.cpp,OperatonMul.h,OperatonDiv.cpp,OperatonDiv.h

Operaton.h


<p>class Operaton<br>{</p><p>public:<br> Operaton();<br> virtual ~Operaton();<br> int numA;<br> int numB;</p><p> virtual int getResult() = 0;</p><p>};</p>

Operaton.cpp

<p>#include "stdafx.h"<br>#include "Operaton.h"</p><p><br>Operaton::Operaton(){</p><p>}</p><p>Operaton::~Operaton(){</p><p>}</p>

OperatonAdd.h

#include "Operaton.h"
 
class OperatonAdd : public Operaton
{
 
public:
 OperatonAdd();
 virtual ~OperatonAdd();
 
 int getResult();
 
};

OperatonAdd.cpp

#include "stdafx.h"
#include "OperatonAdd.h"
 
 
OperatonAdd::OperatonAdd(){
 
}
 
OperatonAdd::~OperatonAdd(){
 
}
 
int OperatonAdd::getResult(){
 return numB + numA;
}

OperatonSub.h

#include "Operaton.h"
 
class OperatonSub : public Operaton
{
 
public:
 OperatonSub();
 virtual ~OperatonSub();
 
 virtual int getResult();
 
};

OperatonSub.cpp

#include "stdafx.h"
#include "OperatonSub.h"
 
OperatonSub::OperatonSub(){
 
}
 
OperatonSub::~OperatonSub(){
 
}
 
int OperatonSub::getResult(){
 return numA * numB;
}

OperatonMul.h

#include "Operaton.h"
 
class OperatonMul : public Operaton
{
 
public:
 OperatonMul();
 virtual ~OperatonMul();
 
 virtual int getResult();
 
};

OperatonMul.cpp

#include "stdafx.h"
#include "OperatonMul.h"
 
OperatonMul::OperatonMul(){
 
}
 
OperatonMul::~OperatonMul(){
 
}
 
int OperatonMul::getResult(){
 return numA - numB;
}

OperatonDiv.h

#include "Operaton.h"
#include <iostream>
 
using namespace std;
 
class OperatonDiv : public Operaton
{
 
public:
 OperatonDiv();
 virtual ~OperatonDiv();
 
 virtual int getResult();
 
};

OperatonDiv.cpp

#include "stdafx.h"
#include "OperatonDiv.h"
 
 
OperatonDiv::OperatonDiv(){
 
}
 
OperatonDiv::~OperatonDiv(){
 
}
 
int OperatonDiv::getResult(){
 int result;
 if(numB!=0)
 result = numA / numB;
 else
 cout<<"您输入的有误,除数不能为0!"<<endl;
 return result;
}

OperatonFactory.h

class OperatonFactory
{
 
public:
 OperatonFactory();
 virtual ~OperatonFactory();
 
 Operaton* create(int operFlag);
 
};

OperatonFactory.cpp

#include "stdafx.h"
#include "Operaton.h"
#include "OperatonAdd.h"
#include "OperatonDiv.h"
#include "OperatonMul.h"
#include "OperatonSub.h"
#include "OperatonFactory.h"
 
 
OperatonFactory::OperatonFactory(){
 
}
 
OperatonFactory::~OperatonFactory(){
 
}
 
Operaton* OperatonFactory::create(int operFlag){
 Operaton* operaton;
 switch(operFlag)
 {
 case OPERATOR_ADD:
 operaton = new OperatonAdd();
 break;
 case OPERATOR_MINUS:
 operaton = new OperatonSub();
 break;
 case OPERATOR_MUTHL:
 operaton = new OperatonMul();
 break;
 case OPERATOR_DIV:
 operaton = new OperatonDiv();
 break;
 default:
 cout<<"输入有错误!"<<endl;
 break;
 }
 return operaton;
}

在这里操作返回的对象,将业务分的更细致,main的代码可改为

#include "stdafx.h"
#include <string>
#include <iostream>
#include "Operaton.h"
#include "OperatonFactory.h"
 
using namespace std;
 
int main(int argc, char* argv[])
{
 int strNumA,strNumB;
 int strOperator;
 cout<<"请输入数字A:\n";
 cin>>strNumA;
 cout<<"请选择运算符号(1,+,2,-,3,*,4,/):\n";
 cin>>strOperator;
 cout<<"请输入数字B:\n";
 cin>>strNumB;
 
 int strResult = 0;
 Operaton *op;
 OperatonFactory* opFactory = new OperatonFactory();
 op = opFactory->create(strOperator);
 op->numA = strNumA;
 op->numB = strNumB;
 strResult = op->getResult();
 cout<<"得到的结果是:"<<strResult;
 return 0;
}

这样,如果继续增加比如求平方,取余就可以不修改main中的内容了。当然现在还没有完全移除if和switch,在下面的历程中会逐一讲到。
上一篇:高校学生在家实践ECS弹性云服务器


下一篇:商品搜索引擎---分词(插件介绍与入门实例)