2016-08-28 71 views
0

我有一个对象为一个工厂保留天气测量。重构详细开关案例陈述

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 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语句可能看起来细,类型:

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; 
    } 
} 

最后,我使用下面的方法来更新每个测量测量可以在将来增长。考虑到这一点以及最佳实践的缘故,是否可以消除这种长时间切换或if/else语句?

+0

您是否了解了Stategy模式? –

+0

我不认为你已经告诉我足够多,我可以说这是否会工作,但我会传达这个想法:在WeatherMeasurementEnum中添加一个方法setMeasuremet(FactoryWeather),然后调用正确的方法工厂。它需要枚举中的抽象方法和每个枚举实例中的实现。 –

回答

3

对于每次测量,您可以在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); 
} 

而事实上,这种方法可以完全消除,因为FactoryWeather的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语句更详细的,它有一个巨大的优势:有没有办法,你可以忘记在引入新类型的度量时处理设置度量:编译器将强制您实现抽象方法。