1. 程式人生 > 其它 >設計模式(1)-使用簡單工廠優化程式碼

設計模式(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,在下面的歷程中會逐一講到。