我使用codeclimate静态分析我的java代码。输出显示: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());
}
}
谢谢
答案 0 :(得分:5)
定义一个调用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);
}
答案 1 :(得分:4)
我们可以编写私有通用方法
为T
和T defaultValue
引入Function<String, T> parser
:
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());
}
}
方法getInteger
,getDouble
,getBoolean
会将其称为通过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);
}
答案 2 :(得分:2)
实际上有太多的异常被重新抛出并被捕获。而且例外情况太不明确了。
对于重构,可以考虑放弃抛出。
当然对于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);