设计模式(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,在下面的历程中会逐一讲到。
- 如何优雅的用Python做接口自动化测试
- 忘记oracle的sys用户密码怎么修改以及Oracle 11g 默认用户名和密码
- hibernate链接数据库链接池c3p0配置
- Oracle中session和processes的设置
- ssh相关原理学习与常见错误总结
- PyQt5 GUI应用程序工具包入门(1)
- grpc部署初体验
- Java中的ReentrantLock和synchronized两种锁机制的对比
- 用Python从零开始创建区块链
- 基于 Python 的僵尸网络将 Linux 机器变成挖矿机器人
- Oracle导入导出常用命令
- Spring Cloud实战小贴士:Zuul处理Cookie和重定向
- 设计模式之代理模式(二)CGLIB动态代理实现
- ios手势复习值之换图片-转场动画(纯代码)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- linux之shell综合例子之定时任务
- spring之配置单例的集合bean,以供多个bean进行引用
- 【python-leetcode25-翻转链表】K 个一组翻转链表
- spring之通过实例工厂方法配置Bean
- 细品redis分布式锁
- 【python-leetcode102-树的宽度遍历】二叉树的层次遍历
- 【python-树的宽度遍历】二叉树的反向层次遍历
- 基于TypeScript封装Axios笔记(二)
- redis高性能数据结构之有序集
- spring之通过静态工厂方法配置Bean
- 【python-leetcode107-树的宽度遍历】二叉树的层次遍历Ⅱ
- spring之通过注解方式配置Bean(一)
- React17新特性:启发式更新算法
- spring之通过FactoryBean配置Bean
- 谱聚类的python实现