设计模式(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
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,在下面的历程中会逐一讲到。