繁体   English   中英

Java代码重复重构

[英]Java code duplication refactoring

我使用codeclimate静态分析我的java代码。 输出说: Similar blocks of code found in 3 locations. Consider refactoring. Similar blocks of code found in 3 locations. Consider refactoring.

什么是重构以下代码而不重复自己而不会丢失“代码可读性”的最佳方法:

public String getString(String component, String key, String defaultValue) throws ConfigException {
    try {
      SingleRequestData config = clientRest.target(this.configServiceUrl).path(CONFIG_ENDPOINT).path(component)
          .path(key).path(defaultValue).request(MediaType.APPLICATION_JSON).get(new GenericType<SingleRequestData>() {
          });
      logger.log(Level.INFO, "Fetched Remote config: {0}={1} for Component: {3}",
          new Object[] { key, config.value, component });
      return config.value;
    } catch (Exception e) {
      logger.log(Level.SEVERE, "{0} : {1}", new Object[] { e.getMessage(), ERROR_MESSAGE });
      throw new ConfigException(e.getMessage() + " " + ERROR_MESSAGE, e.getCause());
    }
  }

  @Override
  public Integer getInteger(String component, String key, int defaultValue) throws ConfigException {
    try {
      String value = this.getString(component, key, String.valueOf(defaultValue));
      return Integer.parseInt(value);
    } catch (Exception e) {
      logger.log(Level.SEVERE, e.getMessage(), e);
      throw new ConfigException(e.getMessage(), e.getCause());
    }
  }

  @Override
  public Double getDouble(String component, String key, double defaultValue) throws ConfigException {
    try {
      String value = this.getString(component, key, String.valueOf(defaultValue));
      return Double.parseDouble(value);
    } catch (Exception e) {
      logger.log(Level.SEVERE, e.getMessage(), e);
      throw new ConfigException(e.getMessage(), e.getCause());
    }
  }

  @Override
  public Boolean getBoolean(String component, String key, boolean defaultValue) throws ConfigException {
    try {
      String value = this.getString(component, key, String.valueOf(defaultValue));
      return Boolean.parseBoolean(value);
    } catch (Exception e) {
      logger.log(Level.SEVERE, e.getMessage(), e);
      throw new ConfigException(e.getMessage(), e.getCause());
    }
  }

谢谢

定义一个调用getString的泛型方法,并使用自定义解析器(在本例中定义为函数接口)将字符串解析为泛型类型:

public <T> T getValue(String component, String key, T defaultValue, Function<String, T> parser) throws ConfigException {
    try {
        String value = this.getString( component, key, String.valueOf(defaultValue) );
        return parser.apply(value);
      } catch (Exception e) {
        logger.log(Level.SEVERE, e.getMessage(), e);
        throw new ConfigException( e.getMessage(), e.getCause() );
      }
}

public Integer getInteger(String component, String key, int defaultValue) throws ConfigException {
    return getValue(component, key, defaultValue, Integer::parseInt );
}

public Double  getDouble(String component, String key, double defaultValue) throws ConfigException {
    return getValue(component, key, defaultValue, Double::parseDouble );
}

public Boolean getBoolean (String component, String key, boolean defaultValue) throws ConfigException {
    return getValue(component, key, defaultValue, Boolean::parseBoolean);
}

我们可以编写一个私有泛型方法
T defaultValueFunction<String, T> parser引入T

private <T> T getT(String component, String key, T defaultValue, Function<String, T> parser) {
    try {
        return parser.apply(this.getString(component, key, String.valueOf(defaultValue)));
    } catch (Exception e) {
        logger.log(Level.SEVERE, e.getMessage(), e);
        throw new ConfigException(e.getMessage(), e.getCause());
    }
}

方法getIntegergetDoublegetBoolean会调用它传递它们的Function<String, T>

public Integer getInteger(String component, String key, int defaultValue) throws ConfigException {
    return getT(component, key, defaultValue, Integer::parseInt);
}

public Double getDouble(String component, String key, double defaultValue) throws ConfigException {
    return getT(component, key, defaultValue, Double::parseDouble);
}

public Boolean getBoolean(String component, String key, boolean defaultValue) throws ConfigException {
    return getT(component, key, defaultValue, Boolean::parseBoolean);
}

实际上有太多的异常被(重新)抛出并被捕获。 而且例外情况太不明确了。

对于重构,可以考虑放弃抛出。

当然对于getInteger和getDouble(调用getString),捕获异常没有意义。

  @Override
  public Integer getInteger(String component, String key, int defaultValue)
              throws ConfigException {
      return Integer.parseInt(getString(component, key, String.valueOf(defaultValue)));
  }

对于Java 8,在一些项目中出现了另一种模式:

public Optional<String> getString(String component, String key) throws ConfigException { ...

public Optional<Integer> getInteger(String component, String key) throws ConfigException {

int value = getInteger(component, key).orElse(defaultValue);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM