前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式(1)-使用简单工厂优化代码

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

作者头像
cloudskyme
发布2018-03-20 11:42:59
6480
发布2018-03-20 11:42:59
举报
文章被收录于专栏:cloudskyme

首先看一段程序,目的是完成一个计算器的计算,

面向过程的写法

代码语言:javascript
复制
#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

代码语言:javascript
复制
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函数

代码语言:javascript
复制
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

代码语言:javascript
复制
class Operaton
{public:
 Operaton();
 virtual ~Operaton();
 int numA;
 int numB; virtual int getResult() = 0;};

 Operaton.cpp

代码语言:javascript
复制
#include "stdafx.h"
#include "Operaton.h"
Operaton::Operaton(){}Operaton::~Operaton(){}

OperatonAdd.h

代码语言:javascript
复制
#include "Operaton.h"

class OperatonAdd : public Operaton
{

public:
	OperatonAdd();
	virtual ~OperatonAdd();

	int getResult();

};

 OperatonAdd.cpp

代码语言:javascript
复制
#include "stdafx.h"
#include "OperatonAdd.h"


OperatonAdd::OperatonAdd(){

}

OperatonAdd::~OperatonAdd(){

}

int OperatonAdd::getResult(){
	return numB + numA;
}

 OperatonSub.h

代码语言:javascript
复制
#include "Operaton.h"

class OperatonSub : public Operaton
{

public:
	OperatonSub();
	virtual ~OperatonSub();

	virtual int getResult();

};

OperatonSub.cpp

代码语言:javascript
复制
#include "stdafx.h"
#include "OperatonSub.h"

OperatonSub::OperatonSub(){

}

OperatonSub::~OperatonSub(){

}

int OperatonSub::getResult(){
	return numA * numB;
}

 OperatonMul.h

代码语言:javascript
复制
#include "Operaton.h"

class OperatonMul : public Operaton
{

public:
	OperatonMul();
	virtual ~OperatonMul();

	virtual int getResult();

};

OperatonMul.cpp

代码语言:javascript
复制
#include "stdafx.h"
#include "OperatonMul.h"

OperatonMul::OperatonMul(){

}

OperatonMul::~OperatonMul(){

}

int OperatonMul::getResult(){
	return numA - numB;
}

 OperatonDiv.h

代码语言:javascript
复制
#include "Operaton.h"
#include <iostream>

using namespace std;

class OperatonDiv : public Operaton
{

public:
	OperatonDiv();
	virtual ~OperatonDiv();

	virtual int getResult();

};

OperatonDiv.cpp

代码语言:javascript
复制
#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

代码语言:javascript
复制
class OperatonFactory
{

public:
	OperatonFactory();
	virtual ~OperatonFactory();

	Operaton* create(int operFlag);

};

OperatonFactory.cpp

代码语言:javascript
复制
#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的代码可改为

代码语言:javascript
复制
#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,在下面的历程中会逐一讲到。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2011-04-07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档