设计模式(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; } |
这样实现了业务逻辑的分离,但是还是没解决刚才的问题,如果再添加操作或业务还需要再修改业务类文件。
第二步 使用简单工厂
工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。
看一下类图的描述
从而得到的几个文件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,在下面的历程中会逐一讲到。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架