• 设计模式(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,在下面的历程中会逐一讲到。

    作者:张锋
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
    更多精彩文章可以观注
    微信公众号 soft张三丰

    微信交流群,添加群主微信,邀请入群
  • 相关阅读:
    从入门到不放弃系列之Koa2
    进击Node.js基础(二)
    进击Node.js基础(一)
    探知浏览器并发请求个数
    Elasticsearch 聚合操作
    Elasticsearch 数据查询
    Elasticsearch 数据操作
    Elasticsearch 映射操作
    Elasticsearch 索引操作
    IDEA类和方法注释模板设置
  • 原文地址:https://www.cnblogs.com/skyme/p/2007613.html
Copyright © 2020-2023  润新知