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