首先看一段程序,目的是完成一个计算器的计算,
面向过程的写法
#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;
}
这样实现了业务逻辑的分离,但是还是没解决刚才的问题,如果再添加操作或业务还需要再修改业务类文件。
第二步 使用简单工厂
工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。
看一下类图的描述
从而得到的几个文件Operaton.cpp,Operaton.h,OperatonAdd.cpp,OperatonAdd.h,OperatonSub.cpp,OperatonSub.h,OperatonMul.cpp,OperatonMul.h,OperatonDiv.cpp,OperatonDiv.h
Operaton.h
class Operaton
{public:
Operaton();
virtual ~Operaton();
int numA;
int numB; virtual int getResult() = 0;};
Operaton.cpp
#include "stdafx.h"
#include "Operaton.h"
Operaton::Operaton(){}Operaton::~Operaton(){}
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,在下面的历程中会逐一讲到。