2016-08-28 125 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語句更詳細的,它有一個巨大的優勢:有沒有辦法,你可以忘記在引入新類型的度量時處理設置度量:編譯器將強制您實現抽象方法。