设计模式(1)-使用简单工厂优化代码

时间:2022-05-04
本文章向大家介绍设计模式(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,在下面的历程中会逐一讲到。