前几天看了一下别人实习生写的代码,有了大量的if/else,虽然if/else可以帮助我们很方便的写出流程控制代码,也便于阅读,但是有时候的过多的if/else看起来确实不舒服,话不多说,先把代码贴出来:
public BaseData updateBaseData(List<DataParams> params) {
BaseData data = new BaseData();
for (DataParams dataParams : params) {
if (dataParams.type == 1) {
data.setCode1(dataParams.code);
} else if (dataParams.type == 2) {
data.setCode2(dataParams.code);
} else if (dataParams.type == 3) {
data.setCode3(dataParams.code);
} else if (dataParams.type == 4) {
data.setCode4(dataParams.code);
} else if (dataParams.type == 5) {
data.setCode5(dataParams.code);
} else if (dataParams.type == 6) {
data.setCode6(dataParams.code);
} else if (dataParams.type == 7) {
data.setCode7(dataParams.code);
} else if (dataParams.type == 8) {
data.setCode8(dataParams.code);
}
}
return data;
}
看到这里 是不是感觉代码又臭又长,咱们话不多说,尝试优化一下?第一时间想到的是switch,效果如下:
public BaseData updateBaseData2(List<DataParams> params) {
BaseData data = new BaseData();
params.stream().forEach(param -> {
switch (param.type) {
case 1:
data.setCode1(param.code);
break;
case 2:
data.setCode2(param.code);
break;
case 3:
data.setCode3(param.code);
break;
case 4:
data.setCode4(param.code);
break;
case 5:
data.setCode5(param.code);
break;
case 6:
data.setCode6(param.code);
break;
case 7:
data.setCode7(param.code);
break;
default:
break;
}
});
return data;
}
唉呀妈呀 还是一样又臭又长,不合格,于是强迫症的我,想到直接回炉重构吧,这里我就主要讲一下反射和工厂模式
首先利用反射来进行重构。代码如下:
/**
* 利用反射重构代码
*
* @param params
* @return
*/
public BaseData updateBaseData3(List<DataParams> params) {
return RefactorCode.getReflect(params);
}
RefactorCode代码如下:
package com.example.demo.com.example.utils;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.example.demo.com.example.wxPay.entity.BaseData;
import com.example.demo.com.example.wxPay.entity.DataParams;
public class RefactorCode {
private static Map<Integer, String> map = new HashMap<>();
static {
map.put(1, "setCode1");
map.put(2, "setCode2");
map.put(3, "setCode3");
map.put(4, "setCode4");
map.put(5, "setCode5");
map.put(6, "setCode6");
map.put(7, "setCode7");
}
public static BaseData getReflect(List<DataParams> params) {
BaseData data = new BaseData();
params.stream().forEach(param -> commom(data, param));
return data;
}
private static void commom(BaseData data, DataParams param) {
String codeName = map.get(param.getType());
try {
Method method = BaseData.class.getMethod(codeName, Integer.class);
method.invoke(data, param.getType());
} catch (Exception e) {
System.out.println(e);
}
}
}
使用反射去掉if/else的原理很简单,使用HashMap建立类型type和需要调用的方法的方法名之间的映射关系,但是知道反射的都知道,在高并发的条件下,反射的效率并不是很乐观,所以我又想到了工厂模式。
工厂模式重构
不知道工厂模式的可以百度一下:
工厂方法模式是把普通工厂就是把简单工厂中具体的工厂类,划分成两层:抽象工厂层+具体的工厂子类层。
为了解决简单工厂的问题,程序员们又想出来一个新的办法,就是设计一个工厂的接口,你想要什么东西,就写个类继承于这个工厂,这样就不用修改什么,直接添加就行了。就相当于,我这个工厂是用来生产鞋子的,而要什么品牌的鞋子具体分到了每个车间,如果新多了一种品牌的鞋子,直接新增一个车间就行了。
- 抽象产品角色:通常是一个抽象类或者接口,里面定义了抽象方法
- 具体产品角色:具体产品的实现类,继承或是实现抽象策略类,通常由一个或多个组成类组成。
- 工厂角色:持有抽象产品类的引用,负责动态运行时产品的选择和构建
按照工厂模式的介绍。我们先要定义一个抽象产品接口AbstractService.代码如下:
package com.example.demo.com.example.wxPay.service;
import com.example.demo.com.example.wxPay.entity.BaseData;
public interface AbstractService {
void refactoringCode(BaseData data, String code);
}
接着我们需要分别实现这七种服务类型的产品,在每种产品中封装不同的服务算法,具体的代码如下所示:
public class Code1Service implements AbstractService {
@Override
public void refactoringCode(BaseData data, String code) {
data.setCode1(code);
}
}
public class Code2Service implements AbstractService {
@Override
public void refactoringCode(BaseData data, String code) {
data.setCode2(code);
}
}
public class Code3Service implements AbstractService {
@Override
public void refactoringCode(BaseData data, String code) {
data.setCode3(code);
}
}
public class Code4Service implements AbstractService {
@Override
public void refactoringCode(BaseData data, String code) {
data.setCode4(code);
}
}
public class Code5Service implements AbstractService {
@Override
public void refactoringCode(BaseData data, String code) {
data.setCode5(code);
}
}
public class Code6Service implements AbstractService {
@Override
public void refactoringCode(BaseData data, String code) {
data.setCode6(code);
}
}
public class Code7Service implements AbstractService {
@Override
public void refactoringCode(BaseData data, String code) {
data.setCode7(code);
}
}
需要是实现工厂角色,在工厂内需要实现产品的方法,使用HashMap维护type和具体产品的对象之间的映射关系,
package com.example.demo.com.example.wxPay.service;
import java.util.HashMap;
import java.util.Map;
public class ServieFactory {
private static Map<Integer, AbstractService> map = new HashMap<>();
static {
map.put(1, new Code1Service());
map.put(2, new Code2Service());
map.put(3, new Code3Service());
map.put(4, new Code4Service());
map.put(5, new Code5Service());
map.put(6, new Code6Service());
map.put(7, new Code7Service());
}
public static AbstractService getCodeService(Integer type) {
return map.get(type);
}
}
最后就是业务层实现产品的方法调用:
/**
* 工厂模式
*
* @param params
* @return
*/
public BaseData updateBaseData4(List<DataParams> params) {
BaseData data = new BaseData();
params.stream().forEach(
param -> ServieFactory.getCodeServicre(param.getType()).refactoringCode(data, param.getCode()));
return data;
}
注:写了这么多,并不是说if/else不够好,只是说明一下学会代码重构的重要性,就拿上述例子来说,我觉得还是if/else 或者switch代码来的直接明了,程序员之路太艰辛,学习永无止境,希望每天都在超越自己,写的不好的也不要喷,技术有限,希望多指导一下,感谢