[英]Refactor a verbose switch case statement
我有一个可以保留单个工厂的天气测量值的对象。
public class FactoryWeather {
// each measurement consists of min, max and average observations.
private Measurement temperature;
private Measurement humidity;
private Measurement ...
public constructor,setters/getters...
}
度量类型定义为如下所示的枚举:
public enum WeatherMeasurementEnum {
// min and max range of single measurement
TEMPERATURE(-50,50),
HUMIDITY(0,100),
...
// validity check for measurements
public boolean isValid(int average) {
return average >= minimum && average <= maximum;
}
}
最后,我使用以下方法更新每个度量:
public void updateWeatherMeasurement(String type, Measurement measurement, FactoryWeather factory) {
WeatherMeasurementEnum m = WeatherMeasurementEnum(type.toUpperCase());
if(!m.isValid(measurement.getAverage())
throw new AppException("Invalid measurement!");
switch(m) {
case TEMPERATURE: factory.setTemperature(measurement);break;
case HUMIDITY: factory.setHumidity(measurement);break;
...
}
}
尽管switch语句看起来不错,但将来的测量类型可能会增加。 考虑到这一点并出于最佳实践的考虑,是否有可能消除这种长开关或if / else语句?
您可以在Map<WeatherMeasurementEnum, Measurement>
存储每个枚举实例的度量值,而不是在FactoryWeather中为每个度量值单独创建一个字段。
然后,您只需要做
public void updateWeatherMeasurement(String type, Measurement measurement, FactoryWeather factory) {
WeatherMeasurementEnum m = WeatherMeasurementEnum(type.toUpperCase());
if (!m.isValid(measurement.getAverage()) {
throw new AppException("Invalid measurement!");
}
factory.setMeasurement(m, measurement);
}
实际上,由于setMeasurement()
方法可以直接验证测量的有效性,因此可以完全消除该方法。
另一个选择是将字段的设置委托给枚举本身:
public enum WeatherMeasurementEnum {
// min and max range of single measurement
TEMPERATURE(-50,50) {
@Override
setMeasurementInFactoryWeather(Measurement m, FactoryWeather fw) {
fw.setTemperature(m);
}
},
HUMIDITY(0,100) {
@Override
setMeasurementInFactoryWeather(Measurement m, FactoryWeather fw) {
fw.setHumidity(m);
}
},
...
// validity check for measurements
public boolean isValid(int average) {
return average >= minimum && average <= maximum;
}
public abstract setMeasurementInFactoryWeather(Measurement m, FactoryWeather fw);
}
尽管它看起来比switch语句更冗长,但它具有巨大的优势:引入新的度量类型时,您不会忘记处理度量的设置:编译器将迫使您实现抽象方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.