前言
实际工作中,很多场景下需要根据不同参数执行不同的处理,首先想到的就是if-else进行判断处理。但是,如果条件太多,且条件中的处理过程比较繁多,这样处理起来就会导致代码臃肿,阅读和维护起来比较困难。因此,为了提高代码质量,往往需要对if-else进行优化。下面以项目中一个实际场景进行入手。
场景
需求:开发一个设备驱动软件,根据显控下发的参数,通过TCP协议发送不同的命令参数给实际设备,以达到远程控制设备的目的。
#include<iostream>
#include<string>
#include<map>
using namespace std;
#define SENDENDFLAG 0x0D //控制指令最后一个字节 回车
#define OK "ok";
/*
模拟TCP客户端,其中有封装好的发送命令的接口和接收数据的接口
*/
class TcpClient{
public:
//发送命令
int SendCMD(string cmd)
{
cout << "发送命令:" << cmd << endl;
return 0;
}
//接收数据
int RecvData()
{
cout << "接收数据:" << endl;
return 0;
}
};
TcpClient tcpCli;
/*
该函数是与显控进行通信的接口:
在该函数内接收显控下发的设备控制指令,然后,以设备协议的命令格式通过TCP发送给设备
*/
string OnUpdate(string inJson)
{
if (inJson=="1") //启动命令
{
string Address = "255"; //地址码
string strCMD = "<" + Address; //命令字
strCMD += "/1_111"; //命令码_操作
strCMD += SENDENDFLAG;
tcpCli.SendCMD(strCMD);
return OK;
}
else if (inJson == "2")//停止命令
{
string Address = "255"; //地址码
string strCMD = "<" + Address; //命令字
strCMD += "/2_222"; //命令码_操作
strCMD += SENDENDFLAG;
tcpCli.SendCMD(strCMD);
return OK;
}
else if (inJson == "3")//自检命令
{
string Address = "255"; //地址码
string strCMD = "<" + Address; //命令字
strCMD += "/3_333"; //命令码_操作
strCMD += SENDENDFLAG;
tcpCli.SendCMD(strCMD);
return OK;
}
else if(inJson == "4")
{
//还有很多其他命令,这里进行省略。。。。
}
else
{
cout << "命令无效!" << endl;
return OK;
}
return "OK";
}
//模拟显控下发启动指令
void test01()
{
string str = "1";
OnUpdate(str);
}
int main()
{
test01();
system("pause");
return 0;
}
策略模式简单应用
应用策略模式重构上述代码,代码如下:
#include<iostream>
#include<string>
#include<map>
using namespace std;
#define SENDENDFLAG 0x0D //控制指令最后一个字节 回车
#define OK "ok";
//定义命令策略接口
class CommandStrategy
{
public:
virtual string Command() = 0;
};
class StartCmd :public CommandStrategy
{
public:
virtual string Command()
{
string Address = "255"; //地址码
string strCMD = "<" + Address; //命令字
strCMD += "/1_111"; //命令码_操作
strCMD += SENDENDFLAG;
return strCMD;
}
};
//关闭命令
class CloseCmd :public CommandStrategy
{
public:
virtual string Command()
{
string Address = "255"; //地址码
string strCMD = "<" + Address; //命令字
strCMD += "/2_222"; //命令码_操作
strCMD += SENDENDFLAG;
return strCMD;
}
};
//查询命令
class SearchCmd :public CommandStrategy
{
public:
virtual string Command()
{
string Address = "255"; //地址码
string strCMD = "<" + Address; //命令字
strCMD += "/3_333"; //命令码_操作
strCMD += SENDENDFLAG;
return strCMD;
}
};
class Character
{
public:
void setCommand(CommandStrategy * comStra) //创建命令对象
{
this->pCom = comStra;
}
void TCPSend()
{
string com = this->pCom->Command(); //生成命令
tcpClient->SendCMD(com); //发送命令
}
public:
CommandStrategy * pCom;
TcpClient *tcpClient;
};
string OnUpdate(string inJson)
{
//创建角色
Character* cha = new Character;
if (inJson == "1")
{
CommandStrategy* strartCmd = new StartCmd;
cha->setCommand(strartCmd);
cha->TCPSend();
delete strartCmd;
delete cha;
return OK;
}
else if (inJson == "2")
{
CommandStrategy* closeCmd = new CloseCmd;
cha->setCommand(closeCmd);
cha->TCPSend();
delete closeCmd;
delete cha;
return OK;
}
else if (inJson == "3")
{
CommandStrategy* searchCmd = new SearchCmd;
cha->setCommand(searchCmd);
cha->TCPSend();
delete searchCmd;
delete cha;
return OK;
}
else
{
cout << "命令无效!" << endl;
delete cha;
return OK;
}
delete cha;
return OK;
}
void test01()
{
string str = "2";
OnUpdate(str);
}
int main()
{
test01();
system("pause");
return 0;
}
策略模式+工厂模式优化if-else
上面的策略模式简单应用例子,没有对if-else进行优化,这里在它的基础上,增加工厂方法,优化if-else繁多问题,代码如下:
#include<iostream>
#include<string>
#include<map>
using namespace std;
#define SENDENDFLAG 0x0D //控制指令最后一个字节 回车
#define OK "ok";
/*
定义命令策略接口
抽象类不能创建对象,只能创建指针对象
*/
class CommandStrategy
{
public:
virtual string Command() = 0;
};
//启动命令
class StartCmd :public CommandStrategy
{
public:
virtual string Command()
{
string Address = "255"; //地址码
string strCMD = "<" + Address; //命令字
strCMD += "/1_111"; //命令码_操作
strCMD += SENDENDFLAG;
return strCMD;
}
};
//关闭命令
class CloseCmd :public CommandStrategy
{
public:
virtual string Command()
{
string Address = "255"; //地址码
string strCMD = "<" + Address; //命令字
strCMD += "/2_222"; //命令码_操作
strCMD += SENDENDFLAG;
return strCMD;
}
};
//查询命令
class SearchCmd :public CommandStrategy
{
public:
virtual string Command()
{
string Address = "255"; //地址码
string strCMD = "<" + Address; //命令字
strCMD += "/3_333"; //命令码_操作
strCMD += SENDENDFLAG;
return strCMD;
}
};
//策略接口
class Character
{
public:
void setCommand(CommandStrategy * comStra) //创建命令对象
{
if (comStra==nullptr)
{
//创建
return;
}
else
{
this->pCom = comStra;
}
}
void TCPSend()
{
if (this->pCom==nullptr)
{
return;
}
else
{
string com = this->pCom->Command(); //生成命令
tcpClient->SendCMD(com); //发送命令
}
}
public:
CommandStrategy * pCom;
TcpClient *tcpClient;
};
//工厂方法
class ServiceFactory{
public:
ServiceFactory()
{
ma.insert(pair<string, CommandStrategy*>("1", new StartCmd));
ma.insert(pair<string, CommandStrategy*>("2", new CloseCmd));
ma.insert(pair<string, CommandStrategy*>("3", new SearchCmd));
}
CommandStrategy* getComService(string comType)
{
if (ma.count(comType) == 0)
{
cout << "命令无效!" << endl;
return nullptr;
}
else
{
return ma.at(comType);
}
}
private:
map<string, CommandStrategy*> ma;
};
//优化后的接口内容如下
string OnUpdate(string inJson)
{
Character* cha = new Character;
ServiceFactory fac;
CommandStrategy* Str=fac.getComService(inJson);
if (Str==nullptr)
{
return "FALSE";
}
else
{
cha->setCommand(Str);
cha->TCPSend();
}
delete Str;
delete cha;
return OK;
}
//模拟显控停止指令
void test02()
{
string str = "2";
OnUpdate(str);
}
int main()
{
test02();
system("pause");
return 0;
}