重构思路-java方法参数过多

问题

参数过多会导致:

  • 不利于调用者理解parameters含义及api的使用条件
  • 可读性、可写性差
  • 同类型的多个参数同时使用时,调用顺序容易搞错了,但编译器不会指出,开发者以为自己写的代码没问题,但可能导致严重Bug

effective java 建议 参数在4个或以下,参数过多时要考虑减少参数。

解决方法

3 ways:

  1. break the method into multiple methods, each which require only a subset of the parameters
  2. create helper classes to hold group of parameters (typically static member classes)
  3. adapt the Builder pattern from object construction to method invocation.

code example

private static final String INDEX_PV_ERR_CODE_METRICNAME = "counter_upggate_pv_index_return_code_prometheus";

private static final String INDEX_PV_ERR_CODE_METRICCOMMENT = "about upggate_pv_index_return_code count";

private static final String INDEX_UV_ERR_CODE_METRICNAME = "counter_upggate_uv_index_return_code_prometheus";

private static final String INDEX_UV_ERR_CODE_METRICCOMMENT = "about upggate_uv_index_return_code count";

private static final String[] INDEX_ERR_CODE_LABELNAMES = {"errMsg", "airline", "flightNo", "deptCode", "destCode", "dateTime"};
    
public static void indexErrCodeCount(String errMsg, String airline, String flightNo, String deptCode, String destCode, String flightDate, String userId, String redisKey, RedisUtil redisUtil, String countType) {
        if (StringUtils.isAnyBlank(errMsg, airline, flightNo, deptCode, destCode, flightDate, countType)) {
            return;
        }
        try {
            if (Boolean.TRUE.toString().equalsIgnoreCase(disconfManager.getConfigureInformation("upgGateIndexReturnCodeCountSwitch", "application", "false"))) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat(Constants.DATE_TEMPLATE);
                String dateTime = simpleDateFormat.format(new Date());

                Map<String, String> objectHashMap = new HashMap<>();
                objectHashMap.put("errMsg", errMsg);
                objectHashMap.put("airline", airline);
                objectHashMap.put("flightNo", flightNo);
                objectHashMap.put("deptCode", deptCode);
                objectHashMap.put("destCode", destCode);
                objectHashMap.put("dateTime", dateTime);
                if (Constants.PROMETHEUS_COUNT_TYPE_PV.equalsIgnoreCase(countType)) {
                    MetricCounterApi.labelinc(INDEX_PV_ERR_CODE_METRICNAME, INDEX_PV_ERR_CODE_METRICCOMMENT, INDEX_ERR_CODE_LABELNAMES, objectHashMap);
                } else if (Constants.PROMETHEUS_COUNT_TYPE_UV.equalsIgnoreCase(countType) && ExposureUtil.upgGateIndexReturnCodeUvCount(flightNo, deptCode, destCode, flightDate, userId, redisKey, redisUtil)) {
                    MetricCounterApi.labelinc(INDEX_UV_ERR_CODE_METRICNAME, INDEX_UV_ERR_CODE_METRICCOMMENT, INDEX_ERR_CODE_LABELNAMES, objectHashMap);
                    Cat.logEvent("Prometheus", "indexReturn" + "_" + airline + "_" + flightNo + "_" + deptCode + "_" + destCode + "_" + dateTime + "_" + errMsg);
                }
            }
        } catch (Exception e) {
            LogUtil.error(Prometheus.class, String.join(",", errMsg, airline, flightNo, deptCode, destCode, countType, "Prometheus indexErrCodeCount exception, e: "), e);
        }
    }

10个参数。。。 太多了,
结合业务和需求,我建议如此改进:

  • erroMsg,airline, flightNo, deptCode, destCode, flightDate 封装进一个对象(prometheusLabels,都是打点相关指标)。且erroMsg 可选(方便扩展),airline,flightNo,deptCode,destCode,flightDate 封装成一个必选对象(多个打点需求都要求必须打这几个指标,且这几个字段组合起来有点实际意义)。 最外层的对象采用builder构造,为了扩展新的可选打点指标。
  • userId, redisKey, redisUtil 封装成一个对象(UvRedis)。uv过滤必须
  • countType整一个 enum出来,有UV,PV 2种类型。 方便日后扩展(可以加enum种类,或者uv,pv这两类型中加新的字段表示某些属性)。 (不过基于需求来说,uv\pv是不太可能扩展了,也可以直接定义2个constants string)

如此便改进到3个参数。 再考虑拆分成多个方法。

更建议去看看《effective java 第3版》 item51.

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值