笔者的博客园地址,有更多Java开发干货:https://www.cnblogs.com/amberJava/
if-else深度优化:巧用状态变更枚举类: https://www.cnblogs.com/amberJava/p/12974976.html
If-else 过多,代码不易读,后人也不敢轻易修改。
个人觉得有如下几种优化方式,网上不胜枚举,可以自行百度,但是小编说的这个方法《if-else深度优化:巧用状态变更枚举》,网上例子不多。
业务场景:
例如在无人仓业务场景中,货架都放在储位上(储位就是地面上标记的某个点),正向流程:货架状态需要从空闲->预占->占用中->预释放->空闲。逆向流程相反。
储位状态需要根据不同的业务场景变更。
正常情况下,A服务请求批量变更储位状态,需要先校验状态是否正确,能否变更,if-else方法。在更新数据库构造更新体时,还需要设置变更前状态,变更后状态,if-else方法。
未优化前:
1.更新前校验
根据不同状态,判断是否可以变更。不能变更,返回错误体。
其中多重if-else嵌套,返回的错误信息也是+拼接
1 for (StorageLocation requestPoint : request.getPointList()) {
2 int taskType = requestPoint.getStorageStatus();
3 if (PositionTaskType.PREOCCUPY.getTaskType().equals(taskType)) { //预占操作
4 if (!StorageStatusEnum.INIT.getStatus().equals(pointDBMap.get(requestPoint.getPoint()).getStorageStatus())) {
5 logger.error("{} 校验{}储位状态异常, 预占操作,状态应该是{} 实际是{},", request.getUuid(), requestPoint.getPoint(),StorageStatusEnum.INIT.getStatus(),pointDBMap.get(requestPoint.getPoint()).getStorageStatus());
6 response.setError(new Error(PositionErrorEnum.SYSTEMHANDLEEERROR.getErrorCode() + "", "校验"+requestPoint.getPoint()+"储位状态异常, 预占操作,状态应该是" + StorageStatusEnum.INIT.getStatus()+ " 实际是" + pointDBMap.get(requestPoint.getPoint()).getStorageStatus()));
7 return response;
8 }
9
10 }else if (PositionTaskType.RELEASEPREOCCUPY.getTaskType().equals(taskType)) { //撤销预占操作
11 if (!StorageStatusEnum.PREOCCUPY.getStatus().equals(pointDBMap.get(requestPoint.getPoint()).getStorageStatus())) {
12 logger.error("{} 校验{}储位状态异常, 撤销预占操作,状态应该是{} 实际是{},", request.getUuid(), requestPoint.getPoint(),StorageStatusEnum.PREOCCUPY.getStatus(),pointDBMap.get(requestPoint.getPoint()).getStorageStatus());
13 response.setError(new Error(PositionErrorEnum.SYSTEMHANDLEEERROR.getErrorCode() + "", "校验"+requestPoint.getPoint()+"储位状态异常, 撤销预占操作,状态应该是" + StorageStatusEnum.PREOCCUPY.getStatus()+ " 实际是" + pointDBMap.get(requestPoint.getPoint()).getStorageStatus()));
14 return response;
15 }
16
17 }else if (PositionTaskType.OCCUPY.getTaskType().equals(taskType)) { //占用操作
18 if (!StorageStatusEnum.PREOCCUPY.getStatus().equals(pointDBMap.get(requestPoint.getPoint()).getStorageStatus())) {
19 logger.error("{} 校验{}储位状态异常, 占用操作,状态应该是{} 实际是{},", request.getUuid(), requestPoint.getPoint(),StorageStatusEnum.PREOCCUPY.getStatus(),pointDBMap.get(requestPoint.getPoint()).getStorageStatus());
20 response.setError(new Error(PositionErrorEnum.SYSTEMHANDLEEERROR.getErrorCode() + "", "校验"+requestPoint.getPoint()+"储位状态异常, 占用操作,状态应该是" + StorageStatusEnum.PREOCCUPY.getStatus()+ " 实际是" + pointDBMap.get(requestPoint.getPoint()).getStorageStatus()));
21 return response;
22 }
23
24 }else if (PositionTaskType.PRERELEASE.getTaskType().equals(taskType)) { //预释放操作
25 if (!StorageStatusEnum.OCCUPY.getStatus().equals(pointDBMap.get(requestPoint.getPoint()).getStorageStatus())) {
26 logger.error("{} 校验{}储位状态异常, 预释放操作,状态应该是{} 实际是{},", request.getUuid(), requestPoint.getPoint(),StorageStatusEnum.OCCUPY.getStatus(),pointDBMap.get(requestPoint.getPoint()).getStorageStatus());
27 response.setError(new Error(PositionErrorEnum.SYSTEMHANDLEEERROR.getErrorCode() + "", "校验"+requestPoint.getPoint()+"储位状态异常, 预释放操作,状态应该是" + StorageStatusEnum.OCCUPY.getStatus()+ " 实际是" + pointDBMap.get(requestPoint.getPoint()).getStorageStatus()));
28 return response;
29 }
30
31 }else if (PositionTaskType.REVOKPRERELEASE.getTaskType().equals(taskType)) { //撤销预释放操作
32 if (!StorageStatusEnum.PRERELEASEOCCUPY.getStatus().equals(pointDBMap.get(requestPoint.getPoint()).getStorageStatus())) {
33 logger.error("{} 校验{}储位状态异常, 预释放操作,状态应该是{} 实际是{},", request.getUuid(), requestPoint.getPoint(),StorageStatusEnum.PRERELEASEOCCUPY.getStatus(),pointDBMap.get(requestPoint.getPoint()).getStorageStatus());
34 response.setError(new Error(PositionErrorEnum.SYSTEMHANDLEEERROR.getErrorCode() + "", "校验"+requestPoint.getPoint()+"储位状态异常, 撤销预释放操作,状态应该是" + StorageStatusEnum.PRERELEASEOCCUPY.getStatus()+ " 实际是" + pointDBMap.get(requestPoint.getPoint()).getStorageStatus()));
35 return response;
36 }
37
38 }else if (PositionTaskType.RELEASE.getTaskType().equals(taskType)) { //预释放操作
39 if (!StorageStatusEnum.PRERELEASEOCCUPY.getStatus().equals(pointDBMap.get(requestPoint.getPoint()).getStorageStatus())) {
40 logger.error("{} 校验{}储位状态异常, 预释放操作,状态应该是{} 实际是{},", request.getUuid(), requestPoint.getPoint(),StorageStatusEnum.PRERELEASEOCCUPY.getStatus(),pointDBMap.get(requestPoint.getPoint()).getStorageStatus());
41 response.setError(new Error(PositionErrorEnum.SYSTEMHANDLEEERROR.getErrorCode() + "", "校验"+requestPoint.getPoint()+"储位状态异常, 预释放操作,状态应该是" + StorageStatusEnum.PRERELEASEOCCUPY.getStatus()+ " 实际是" + pointDBMap.get(requestPoint.getPoint()).getStorageStatus()));
42 return response;
43 }
44 }
45 }
2.构造更新体代码。同样问题,if-else过多
1 private QueryPoint getUpdatePoint( BatchPreReleaseStorageLocationRequest request,String operatorName,StorageLocation requestPoint){
2 QueryPoint updatePoint = new QueryPoint();
3 //条件
4 updatePoint.setAreaId(request.getMapAreaId());
5 updatePoint.setOrgNo(request.getOrgNo());
6 updatePoint.setDistributeNo(request.getDistributeNo());
7 updatePoint.setWarehouseNo(request.getWarehouseNo());
8 updatePoint.setPositionId(requestPoint.getPoint());
9 updatePoint.setUpdateUser(operatorName);
10 updatePoint.setContainerNo(requestPoint.getContainerNo());
11
12 if (PositionTaskType.PREOCCUPY.getTaskType().equals(requestPoint.getStorageStatus())) { //预占操作
13 updatePoint.setStorageStatus(StorageStatusEnum.PREOCCUPY.getStatus());
14 updatePoint.setOldStorageStatus(StorageStatusEnum.INIT.getStatus());
15 }else if (PositionTaskType.RELEASEPREOCCUPY.getTaskType().equals(requestPoint.getStorageStatus())) { //撤销预占操作
16 updatePoint.setStorageStatus(StorageStatusEnum.INIT.getStatus());
17 updatePoint.setOldStorageStatus(StorageStatusEnum.PREOCCUPY.getStatus());
18 }else if (PositionTaskType.OCCUPY.getTaskType().equals(requestPoint.getStorageStatus())) { //占用操作
19 updatePoint.setStorageStatus(StorageStatusEnum.OCCUPY.getStatus());
20 updatePoint.setOldStorageStatus(StorageStatusEnum.PREOCCUPY.getStatus());
21 }else if (PositionTaskType.PRERELEASE.getTaskType().equals(requestPoint.getStorageStatus())) { //预释放操作
22 updatePoint.setStorageStatus(StorageStatusEnum.PRERELEASEOCCUPY.getStatus());
23 updatePoint.setOldStorageStatus(StorageStatusEnum.OCCUPY.getStatus());
24 }else if (PositionTaskType.REVOKPRERELEASE.getTaskType().equals(requestPoint.getStorageStatus())) { //撤销预释放操作
25 updatePoint.setStorageStatus(StorageStatusEnum.OCCUPY.getStatus());
26 updatePoint.setOldStorageStatus(StorageStatusEnum.PRERELEASEOCCUPY.getStatus());
27 }else if (PositionTaskType.RELEASE.getTaskType().equals(requestPoint.getStorageStatus())) { //预释放操作
28 updatePoint.setStorageStatus(StorageStatusEnum.INIT.getStatus());
29 updatePoint.setContainerNo("");
30 updatePoint.setOldStorageStatus(StorageStatusEnum.PRERELEASEOCCUPY.getStatus());
31 }
32 return updatePoint;
33 }
优化后:
1.新增一个状态变更枚举类
public enum PositionTaskTypeStatus {
PREOCCUPY(1, "预占用",0,1),
RELEASEPREOCCUPY(2, "释放预占用",1,0),
OCCUPY(3, "占用",1,10),
PRERELEASE(4, "预释放",10,3),
REVOKPRERELEASE(5, "撤销预释放",3,10),
RELEASE(6, "释放",3,0),
;
private Integer taskType;
private String taskName;
private Integer fromStatus;
private Integer toStatus;
private static Map map = new HashMap<>();
static {
for (PositionTaskTypeStatus task : PositionTaskTypeStatus.values()) {
map.put(task.getTaskType(), task);
}
}
PositionTaskTypeStatus(Integer taskType, String taskName, Integer fromStatus, Integer toStatus) {
this.taskType = taskType;
this.taskName = taskName;
this.fromStatus = fromStatus;
this.toStatus = toStatus;
}
public Integer getTaskType() {
return taskType;
}
public void setTaskType(Integer taskType) {
this.taskType = taskType;
}
public String getTaskName() {
return taskName;
}
public void setTaskName(String taskName) {
this.taskName = taskName;
}
public Integer getFromStatus() {
return fromStatus;
}
public void setFromStatus(Integer fromStatus) {
this.fromStatus = fromStatus;
}
public Integer getToStatus() {
return toStatus;
}
public void setToStatus(Integer toStatus) {
this.toStatus = toStatus;
}
public static Map getMap() {
return map;
}
public static void setMap(Map map) {
PositionTaskTypeStatus.map = map;
}
public static String getTaskNameByTaskType(Integer taskType) {
String taskName = "";
for (PositionTaskTypeStatus e : PositionTaskTypeStatus.values()) {
if (e.taskType.equals(taskType)) {
taskName = e.taskName;
}
}
return taskName;
}
public static boolean contains(Integer taskType){
if(null == taskType){
return false;
}
return map.containsKey(taskType)?true:false;
}
public static PositionTaskTypeStatus getEnumByKey(Integer taskType){
return map.get(taskType);
}
/**
* 操作类型、原始值是否可以修改
* @param taskType
* @param originalValue
* @return
*/
public static boolean verify(Integer taskType,Integer originalValue){
if(null==getEnumByKey(taskType)){
return false;
}
if(!getEnumByKey(taskType).getFromStatus().equals(originalValue)){
return false;
}
return true;
}
2.更新前校验代码片段。
枚举状态变更类+google的前置检查方法,一行搞定。
//校验状态是否在枚举之内
for(StorageLocation requestPoint : request.getPointList()){
Preconditions.checkArgument(PositionTaskTypeStatus.contains(requestPoint.getStorageStatus()),"%s操作类型%s不存在",requestPoint.getPoint(),requestPoint.getStorageStatus());
}
3.构造更新体代码
1 private QueryPoint getUpdatePoint( BatchPreReleaseStorageLocationRequest request,StorageLocation requestPoint){
2 QueryPoint updatePoint = new QueryPoint();
3 updatePoint.setAreaId(request.getMapAreaId());
4 updatePoint.setOrgNo(request.getOrgNo());
5 updatePoint.setDistributeNo(request.getDistributeNo());
6 updatePoint.setWarehouseNo(request.getWarehouseNo());
7 updatePoint.setPositionId(requestPoint.getPoint());
8 updatePoint.setUpdateUser(request.getOperatorName());
9 updatePoint.setContainerNo(requestPoint.getContainerNo());
10 updatePoint.setStorageStatus(PositionTaskTypeStatus.getEnumByKey(requestPoint.getStorageStatus()).getToStatus()); //枚举类,设置更新状态
11 updatePoint.setOldStorageStatus(PositionTaskTypeStatus.getEnumByKey(requestPoint.getStorageStatus()).getFromStatus()); //枚举类 设置原始状态
12 return updatePoint;
13 }
看过后有没有恍然大悟的感觉,看看您代码中是否有这样的场景,赶快优化吧~~
笔者之后遇到的项目,都按照这种思想编码。有的项目业务状态多大20多种,if-else会看的很头疼。
持续优化:
参考: 用Java8 Lambda重构简单工厂模式 https://segmentfault.com/a/1190000021803985ttps://segmentfault.com/a/1190000021641277