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

简介: 首先看一段程序,目的是完成一个计算器的计算, 面向过程的写法 #include "stdafx.h" #include #include using namespace std; int main(int argc, char* argv[]) { int strN...

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

面向过程的写法

#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;
}

这样实现了业务逻辑的分离,但是还是没解决刚才的问题,如果再添加操作或业务还需要再修改业务类文件。

第二步 使用简单工厂

工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类。

 看一下类图的描述

img_0dbcf81eab969842b036002fd5997cc6.jpg

从而得到的几个文件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,在下面的历程中会逐一讲到。

目录
相关文章
|
前端开发 IDE JavaScript
【inBuilder 低代码开发实验室】使用inbuilder完成UBML低代码设计开发
【inBuilder 低代码开发实验室】使用inbuilder完成UBML低代码设计开发
280 0
|
Java Linux 微服务
linux中一键杀死springclud等各个java进程
linux中一键杀死springclud等各个java进程
131 0
|
小程序 程序员 API
小程序(uniapp)上传头像至OSS(阿里云)--保姆级
前言 自微信小程序改版以来,现在获取用户的头像和昵称就不能直接通过wx.getUserInfo获取了。而是需要用户主动在登录后填写自己的昵称和头像,微信只是提供一个一键填写的快捷操作让用户直接使用自己已有的微信昵称或头像。
5085 1
简书Markdown语法指南
Markdown 的目标是实现「易读易写」。 1.标题大小 从‘#’到‘#####’ 挨个试试总能找到你满意的 标题演示 2.单行代码 ``:英文键盘 esc下面那个键UserMapper:.
1044 0
电脑里的记事本文件永久删除怎么办
小楠电脑上的记事本文件被玩电脑的弟弟删除了,后来发现那个记事本里有很多资料和帐号,他赶紧去电脑回收站找了半天也没找到。问了弟弟才知道他不小心按到Shift+Delete,那可是永久删除啊!把他气得够呛… 他也只能去网上找一些恢复的办法,网上提供的办法都大同小异,而且那些带有恢复功能的应用基本都是收费的,这让他很不开心,慢慢就失去了寻找的兴趣。
1576 0
|
5天前
|
数据采集 人工智能 自然语言处理
3分钟采集134篇AI文章!深度解析如何通过云无影AgentBay实现25倍并发 + LlamaIndex智能推荐
结合阿里云无影 AgentBay 云端并发采集与 LlamaIndex 智能分析,3分钟高效抓取134篇 AI Agent 文章,实现 AI 推荐、智能问答与知识沉淀,打造从数据获取到价值提炼的完整闭环。
389 93
|
6天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~