設計模式(1)-使用簡單工廠優化程式碼
阿新 • • 發佈:2022-05-04
首先看一段程式,目的是完成一個計算器的計算,
面向過程的寫法
#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,在下面的歷程中會逐一講到。