2016-08-28 5 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... 

} 

測定タイプが列挙以下のようなのように定義される:switch文は、の種類を微に見えるかもしれないが

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

} 

:最後に

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)'メソッドを追加します。工場。 enumには抽象メソッドが必要で、各enumインスタンスには実装が必要です。 –

答えて

3

測定ごとにFactoryWeatherに別のフィールドを持つのではなく、各enumインスタンスの測定値を格納するMap<WeatherMeasurementEnum, Measurement>を持つことができます。

あなたはその後、ちょうど

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文よりも冗長に見えるかもしれないが、それは大きな利点があります:あなたは忘れることができる方法はありません新しいタイプの測定が導入されたときの測定の設定を処理するために、コンパイラは抽象メソッドを実装するように強制します。