代码优化之冗余的if else
在实际的编码过程中,我们不可避免的会使用到if else语句做条件判断。我前两天偶然见到一个方法中竟包含五十余个if
else语句,这样的代码一眼望去着实规整,但对于有强迫症的程序猿来讲这就是一大灾难。于是我怀着一颗强迫的心仔细看了
一遍代码,代码思路其实就是利用if else根据变量的值实现不同的操作,代码结构类似于:
/**
* 根据var的值进行不同的操作
* @param var
*/
public void HugeIfElse(String var){
if(StringUtils.equals("var1", var)){
func1();
}else if(StringUtils.equals("var2", var)){
func2();
}else if(StringUtils.equals("var3", var)){
func3();
}else if(StringUtils.equals("var4", var)){
func4();
}else if(StringUtils.equals("var5", var)){
func5();
}
}
其实根据变量的具体值进行具体的操作利用ifelse是最常见的用法,如果数量较少还是可行的,但是一旦数量超过五个,
这样的代码就可以算是垃圾代码了。那针对这种情况纠结如何优化呢?
有人说可以利用switch,因为在jdk1.7之后switch已经支持String类型,那我们先把上诉代码变为switch的形式:
/**
* 根据var的值进行不同的操作
* @param var
*/
public void HugeIfElse(String var){
switch(var){
case "var1":func1();break;
case "var2":func2();break;
case "var3":func3();break;
case "var4":func4();break;
case "var5":func5();break;
default:break;
}
}
看上去写法上好像确实简便了许多,但是很明显这是一种自欺欺人的表现,这两种形式的复杂度并没有降低,而且不能兼
容低版本的jdk,因此这种写法其实是不可取的。接下来为大家提供一种基于多态的优化方式。基本思路:1、抽象
出接口,将不同情况的操作定义为具体的类并实现此接口;2、建立变量值与对象之间的映射关系(可以考虑map)。
首先:创建接口
package com.demo.ww.utilInterface;
public interface IBaseInterface {
//映射关系
@SuppressWarnings("serial")
public final Map<String, String> relation = new HashMap<String, String>(){
{
put("var1", new BaseInterfaceIml1);
put("var2", new BaseInterfaceIml2);
put("var3", new BaseInterfaceIml3);
put("var4", new BaseInterfaceIml4);
put("var5", new BaseInterfaceIml5);
}
};
//公共方法
public void execute();
}
然后封装所有实现类(例子中的5个)
第一个类 对应var的值为”var1”:
package com.demo.ww.utilInterface.impl;
public class BaseInterfaceIml1 implements IBaseInterface{
public void execute(){
func1();
}
}
第二个类 对应var的值为”var2”:
package com.demo.ww.utilInterface.impl;
public class BaseInterfaceIml2 implements IBaseInterface{
public void execute(){
func2();
}
}
第三个类 对应var的值为”var3”:
package com.demo.ww.utilInterface.impl;
public class BaseInterfaceIml3 implements IBaseInterface{
public void execute(){
func3();
}
}
剩下两个类类似。最后调用方式如下:
/**
* 根据var的值进行不同的操作
* @param var
* @return
*/
public void HugeIfElse(String var){
try {
//获取实体类名
IBaseInterface classInstance = (IBaseInterface)IBaseInterface.relation.get(var);
if(null == classInstance){
log.error("没有获取到"+var+"对应的实例");
return ;
}
} catch (Exception e) {
log.error("获取"+var+"对应的实例失败",e);
}
baseInterface.execute();
}
这种方式的好处在于如果以后需要再添加if else,只需要添加对应的类和map中的对应方式即可,扩展性、复用性、维护性
都比较好。 其实这种现象在编码过程中很常见,很多时候是由于第一个人在编码时只有少数的情况就写了几个if else,第二个
人后来维护又加了几个,以此类推。虽然每个人加的都很少,但是总体就很大了,到最后就成了连篇的if else,希望大家的
代码中不要出现类似的问题哦!
但是要注意的是并不是每种冗余的if else都适用这种优化方式,例如:
/**
* mysql根据类型简拼获取字段类型
*
* @param dataType
* @return
*/
public String mysqlDataType(String dataType) {
if ("N".equals(dataType)) {
return "decimal";
} else if ("INT".equals(dataType)) {
return "int";
} else if ("DEC".equals(dataType)) {
return "decimal";
} else if ("M".equals(dataType)) {
return "N(17,2)";
} else if ("SI".equals(dataType)) {
return "smallint";
} else if ("TI".equals(dataType)) {
return "tinyint";
} else if ("BI".equals(dataType)) {
return "bigint";
} else if ("MI".equals(dataType)) {
return "mediumint";
} else if ("FL".equals(dataType)) {
return "float";
} else if ("DL".equals(dataType)) {
return "double";
} else if ("BIN".equals(dataType)) {
return "binary";
} else if ("VBIN".equals(dataType)) {
return "varbinary";
} else if ("LONGBLOB".equals(dataType)) {
return "longblob";
} else if ("C".equals(dataType)) {
return "char";
} else if ("VC".equals(dataType)) {
return "varchar";
} else if ("TEXT".equals(dataType)) {
return "text";
} else if ("D".equals(dataType)) {
return "date";
} else if ("DT".equals(dataType)) {
return "datetime";
}
return dataType;
}
这段代码主要是根据类型简拼去获取字段的类型。像这种简单的判断用一个map就可以搞定了。如下先定义一个对应关系的map
/** 简拼与数据库类型之间的对应关系 */
Map<String, String> dbtype = new HashMap<String, String>(){
{
put("VC", "varchar");
put("N", "decimal");
put("INT", "int");
···
···
···
}
};
将原来的方法改为
/**
* mysql根据类型简拼获取字段类型
*
* @param dataType
* @return
*/
public String mysqlDataType(String dataType) {
return dbtype.get(dataType);
}