首先看一段程序,目的是完成一个计算器的计算,
面向过程的写法
#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
<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,在下面的历程中会逐一讲到。