posts - 146,comments - 15,views - 13万

业务背景:

最近有同事在做门禁未生效预警系统。审核提交的代码时,发现了一段熟悉的内容,内容如下。

这段代码看着很眼熟,查阅了一下,发现之前悦荟在之前优化其它服务的时候优化过这段代码,暂时就不追究为什么这段代码竟然存在于多个服务中了,还是尽早改掉就好。通过阅读代码,发现按照上次的经验,从根源处ThresholdInfoData的结构进行重新设计优化,可能不好修改,设计的地方会比较多。于是考虑采用一种简洁快速的方式,先优化掉这种if else过多的情况——表驱动的方式。

修改前代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
private void setThresholdValue(ThresholdInfoData thresholdInfoData, net.sf.json.JSONArray thresholds) {
    if (thresholds.isEmpty()) {
        logger.info("thresholds is null");
        return;
    
    int thresSize = thresholds.size();
    for (int j = 0; j < thresSize; j++) {
        if (thresholds.getJSONObject(j).has(Constant.VALUE)) {
            String threshold_desc = thresholds.getJSONObject(j).getString(Constant.THRESHOLD_DESC);
            double value = Double.parseDouble(thresholds.getJSONObject(j).getString(Constant.VALUE));
            int validityValue = Constant.ZERO;
            validityValue = thresholds.getJSONObject(j).get("validity") == null ? validityValue : thresholds.getJSONObject(j).getInt("validity");
            value = validityValue == 1 ? Constant.TEN_THOUSAND : value;
            if (threshold_desc.equals(Constant.OPENINGRATE)) {
                thresholdInfoData.setOpeningRate(value);
            } else if (threshold_desc.equals(Constant.COMPLE_TOTAL_ERROR_THRESHOLD)) {
                thresholdInfoData.setCompileError(value);
                thresholdInfoData.setCompileValidity(validityValue);
            } else if (threshold_desc.equals(Constant.CMTRICS_UNSAFE_FUNC_THRESHOLD)) {
                   thresholdInfoData.setCscheckerUnsafe(value);
                   thresholdInfoData.setCscheckerUnsafeValidity(validityValue);
            } else if (threshold_desc.equals(Constant.CMETRICS_REDUNDANT_CODE_TOATL_THRESHOLD)) {
                 thresholdInfoData.setCscheckerIf0(value);
                 thresholdInfoData.setCscheckerIf0Validity(validityValue);
        } else if (threshold_desc.equals(Constant.STATIC_ERROR)) {
                 thresholdInfoData.setStatiError(value);
                 thresholdInfoData.setStatiErrorValidity(value);
        } else if (threshold_desc.equals(Constant.SOURCEMONITOR_NEW_METHOD_COMPLEXITY_THRESHOLD)) {
                 thresholdInfoData.setSourcemonitorComplexity(value);
        } else if (threshold_desc.equals(Constant.SOURCEMONITOR_NEW_METHOD_STATEMENT_THRESHOLD)) {
                thresholdInfoData.setSourcemonitorStatement(value);
        } else if (threshold_desc.equals(Constant.CMETRICS_CODE_DUPLICATION_RATIO_THRESHOLD)) {
                thresholdInfoData.setSimianDuplicationpercent(value);
                thresholdInfoData.setSimianDuplicationpercentValidity(validityValue);
        } else if (threshold_desc.equals(Constant.CMETRICS_FILE_DUPLICATION_RATIO_THRESHOLD)) {
                thresholdInfoData.setMetricRepeatFilesRate(value);
                thresholdInfoData.setMetricRepeatFilesRateValidity(validityValue);
        } else if (threshold_desc.equals(Constant.LLT_TC_CHANGED_COVERAGE_THRESHOLD)) {
             thresholdInfoData.setLltChangedCoverage(value);
        } else if (threshold_desc.equals(Constant.LLT_TC_PASS_PERCENT_THRESHOLD)) {
            thresholdInfoData.setLltPassPercent(value);
        }
        }
    }
}

修改后的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
private void setThresholdValue(ThresholdInfoData thresholdInfoData, net.sf.json.JSONArray thresholds) {
        if (thresholds.isEmpty()) {
                logger.info("thresholds is null");
                return;
        }
        int thresSize = thresholds.size();
        for (int j = 0; j < thresSize; j++) {
            if (thresholds.getJSONObject(j).has(Constant.VALUE)) {
                String threshold_desc = thresholds.getJSONObject(j).getString(Constant.THRESHOLD_DESC);
                double value = Double.parseDouble(thresholds.getJSONObject(j).getString(Constant.VALUE));
                 int validityValue = Constant.ZERO;
                 validityValue = thresholds.getJSONObject(j).get("validity") == null ? validityValue : thresholds.getJSONObject(j).getInt("validity");
                 value = validityValue == 1 ? Constant.TEN_THOUSAND : value;
                 Map<String, BiConSumer<Double, Integer>> actionMappings = getComparisionTable(thresholdInfoData);
                 try {
                        actionMappings.get(threshold_desc).accept(value, validityValue);
                } catch (NullPointerException e) {
                        logger.warn("get" + threshold_desc + " is null");
                }
            }
        }
}
 
 
// 生成阈值描述和不同赋值方法的对照表
private Map<String, BiConsumer<Double, Integer>> getComparisionTable(ThresholdInfoData thresholdInfoData) {
    Map<String, BiConsumer<Double, Integer>> actionMappings = new HashMap<>();
    actionMappings.put(Constant.OPENNINGRATE, (a, b) -> {thresholdInfoData.setOpeningRate(a);});
 actionMappings.put(Constant.COMPILE_TOTAL_ERROR_THRESHOLD, (a, b) -> {
    thresholdInfoData.setCompileError(a);
    thresholdInfoData.setCompileValidity(b);
 });
  actionMappings.put(Constant.CSCHECKER_UNSAFE_FUNC_THRESHOLD, (a, b) -> {
    thresholdInfoData.setCscheckUnsafe(a);
    thresholdInfoData.setCscheckerUnsafeValidity(b);
 });
actionMappings.put(Constant.CMTRICS_REDUNDANT_CODE_TOATL_THRESHOLD, (a, b) -> {
    thresholdInfoData.setCscheckerIf0(a);
    thresholdInfoData.setCscheckerIf0Validity(b);
 });
actionMappings.put(Constant.STATIC_ERROR, (a, b) -> {
    thresholdInfoData.setStatiError(a);
    thresholdInfoData.setStatuErrorValidity(b);
 });
actionMappings.put(Constant.SOURCEMONITOR_NEW_METHOD_COMPLEXITY_THRESHOLD, (a, b) -> {
    thresholdInfoData.setSourcemonitorComplexity(a);
 });
actionMappings.put(Constant.SOURCEMONITOR_NEW_METHOD_STATEMNET_THRESHOLD, (a, b) -> {
    thresholdInfoData.setSourcemonitorStatement(a);
 });
actionMappings.put(Constant.CMETRICS_CODE_DUPLICATION_RATIO_THRESHOLD, (a, b) -> {
    thresholdInfoData.setSimianDuplicationpercent(a);
    thresholdInfoData.setSimianDuplicationpercentValidity(b);
 });
actionMappings.put(Constant.CMETRICS_FILE_DUPLICATION_RATIO_THRESHOLD, (a, b) -> {
    thresholdInfoData.setMetricRepeatFilesRate(a);
    thresholdInfoData.setMetricRepeatFilesRateValidity(b);
 });
actionMappings.put(Constant.LLT_TC_CHANGED_COVERAGE_THRESHOLD, (a, b) -> {
    thresholdInfoData.setLltChangedCoverage(a);
 });
actionMappings.put(Constant.LLT_TC_PASS_PERCENT_THRESHOLD, (a, b) -> {
    thresholdInfoData.setLltPassPercent(a);
 });
  return actionMappings;
}

  

总结:

对于上述这种逻辑表达模式固定的if else代码,适用表驱动的方式进行解决。即通过某种映射关系,将逻辑表达式用表格的方式表示;再使用表格查找的方式,找到某个输入所对应的处理函数,适用这个处理函数进行运算。除表驱动的方式,还可以考虑使用反射、策略模式+注解等多种方式处理。

当然,最好的方式还是在最初设计的时候,就做好充分的考虑和结构设计,从根源上避免产生这样的代码。

posted on   人无名,则可专心练剑  阅读(80)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
历史上的今天:
2021-05-06 【数据库】Oracle -- 一文了解Oracle数据库开发知识地图
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示