2011-12-03 13 views
1

は、私はほとんど同様の4つの方法があるが、私は彼らに私はそれらをリファクタリングすることができますどのようにこれらのメソッドをどのようにリファクタリングするのですか?

public String listWeatherConditions() 
{ 
    String retVal = ""; 
    SimpleDateFormat formatter = new SimpleDateFormat("hh:mm a"); 
    for(Map.Entry<String , ArrayList<Weather>> entry : this.weathers.entrySet()) 
    { 
     retVal = String.format("\n Data From %s \n", entry.getKey()); 
     retVal += String.format("displaying \tWeather Conditions hPa\n",""); 
     for (Weather element : this.weathers.get(entry.getKey())) 
       { 

        retVal += String.format("%s\t\t%s\n",formatter.format(element.getCalculatedDate()) , element.getConditions()); 
       } 
    } 

    retVal += "--------------------"; 
    return retVal; 
} 

public String listWind() 
{ 
    String retVal = ""; 
    SimpleDateFormat formatter = new SimpleDateFormat("hh:mm a"); 
    for(Map.Entry<String , ArrayList<Weather>> entry : this.weathers.entrySet()) 
    { 
     retVal = String.format("\n Data From %s \n", entry.getKey()); 
     retVal += String.format("displaying \tWind Direction\tWind SpeedKm/h\tWindDirDegrees\n",""); 
     for (Weather element : this.weathers.get(entry.getKey())) 
       { 

        retVal += String.format("%s\t\t%s\t\t%s\t\t%d\n", formatter.format(element.getCalculatedDate()), element.getWindDirection() , element.getWindSpeedKmh() , element.getWindDirDegrees()); 
       } 
    } 

    retVal += "--------------------"; 
    return retVal; 

} 

をリファクタリングする方法を見つけ出すことはできませんか?

+0

の書式設定の戦略を定義するためにStrategyパターンを使用して、私は唯一の2つの方法を数えます。 –

+0

便宜のためにここに2つだけコピーしました –

答えて

4

少なくとも2つの点で違いがあります。異なるヘッダーがあり、異なる書式があります。ジェネリックメソッドでは、Stringパラメータを渡すだけでさまざまなヘッダーを処理できます。第2の問題は、文字列をどのようにフォーマットするかを示すパラメータを含めることによって対処することができ、これを対応してメソッドで処理することができます。

本当に普遍的な方法が必要な場合は、インターフェイス経由で行うことができます。

interface WeatherFormatter { 
    String formatWeather(Weather weather); 
} 

あなたの一般的な方法:このような何か

public String listConditions(String header, WeatherFormatter weatherFormatter) { 
    String retVal = ""; 
    SimpleDateFormat formatter = new SimpleDateFormat("hh:mm a"); 
    for(Map.Entry<String , ArrayList<Weather>> entry : this.weathers.entrySet()) { 
     retVal = String.format("\n Data From %s \n", entry.getKey()); 
     retVal += header; 
     for (Weather element : this.weathers.get(entry.getKey())) { 
      retVal += weatherFormatter.formatWeather(weather); 
     } 
    } 
    retVal += "--------------------"; 
    return retVal; 
} 

そして、あなたはこのようなあなたのジェネリックメソッドを呼び出す:

listConditions("displaying \tWeather Conditions hPa\n", new WeatherFormatter() { 
    String formatWeather(Weather weather) { 
     return String.format("%s\t\t%s\n", formatter.format(weather.getCalculatedDate()), weather.getConditions()); 
    } 
}); 

もう一つのアイデア:あなたは私の提案の両方を組み合わせることができます。メソッドのパラメータはインターフェイスだけでなく、代わりにこのインターフェイスを実装するenumを作成します。あなたのenum宣言では、各定数に対してformatWeather()メソッドを実装します。それは非常にオブジェクト指向の設計になります。

+0

+1です。私とまったく同じアイデアですが、より良い、より早い説明が付いています。 –

+0

+1ちょうど同じ考えを投稿しました:D – GETah

+0

ここで言うことを実装する方法についていくつかの助けが必要です。これはこのようなことを初めてリファクタリングするときです。一般的なループを実装する方法は実際には分かりませんそれから動的な価値を得るために、私はgtalkにそれに答えることを願っています。 –

2

コードを正しく読んでいる場合は、ループの天気オブジェクトをどのように扱うかが唯一の違いがあるようです。この場合、文字列を追加するだけです。 1つの方法でループを行い、実際に "これで何をするか"を渡すオブジェクトに委譲させることが価値があるかもしれません。

たとえば、 "do何か」部品...

public Interface WeatherWork { 
    public String formatWeatherString(Weather weather); 
} 

そして、あなたが望む出力の種類ごとに一度それを実装...

public class WindWorker implements WeatherWork { 
    public String formatWeatherString(Weather weather) { 
     return String.format("%s\t\t%s\n",formatter.format(weather.getCalculatedDate()) , weather.getConditions()); 
    } 
} 

そして、これらの新しいオブジェクトの1つを取るためにあなたの天気ループのコードを再実装。 ..

public String listWind() { 
    return formatWeather(new WindWorker()); 
} 

とformatWeather()ループを行うだろう...

public String formatWeather(WeatherWork worker) { 
    String retVal = ""; 
    SimpleDateFormat formatter = new SimpleDateFormat("hh:mm a"); 
    for(Map.Entry<String , ArrayList<Weather>> entry : this.weathers.entrySet()) { 
    retVal = String.format("\n Data From %s \n", entry.getKey()); 
    for (Weather element : this.weathers.get(entry.getKey())) { 
     retVal += worker.formatWeatherString(element); 
    } 

    retVal += "--------------------"; 
    return retVal; 
} 

編集:おっと、私はヘッダを逃しました。あなたはアイデアを得る、あなたはWeatherWorkerにそれらを置くことができます。インターフェイスにメソッドを追加してヘッダーを返し、実装クラスに実装するだけです。

+1

+1私とまったく同じアイデア:これはラムダ述語 – GETah

+1

@GETahでもっと簡単になりました。私はこの質問を見たら、私は同じことを考えました... – Todd

0

提案:フライ

public String listWeatherFeature(IFormatterStrategy formatStrategy){ 
    String retVal = ""; 
    for(Map.Entry<String , ArrayList<Weather>> entry : this.weathers.entrySet()){ 
     retVal = String.format("\n Data From %s \n", entry.getKey()); 
     for (Weather element : this.weathers.get(entry.getKey())){ 
      retVal += formatStrategy.formatElement(element); 
     } 
    } 
    retVal += "--------------------"; 
    return retVal; 
} 

public interface IFormatterStrategy{ 
    String formatElement(Weather element); 
} 

public class WindFormatterStrategy implements IFormatter{ 
    String formatElement(Weather element){ 
     SimpleDateFormat formatter = new SimpleDateFormat("hh:mm a"); 
     return String.format("%s\t\t%s\t\t%s\t\t%d\n", formatter.format(element.getCalculatedDate()), element.getWindDirection() , element.getWindSpeedKmh() , element.getWindDirDegrees()); 
    } 
} 

public class WeatherFormatterStrategy implements IFormatter{ 
    String formatElement(Weather element){ 
     SimpleDateFormat formatter = new SimpleDateFormat("hh:mm a"); 
     return String.format("%s\t\t%s\n",formatter.format(element.getCalculatedDate()) , element.getConditions()); 
    } 
} 

// Usage 
// Wind: 
String result = String.format("displaying \tWeather Conditions hPa\n",""); 
result += listWeatherFeature(new WeatherFormatterStrategy()); 
// Weather 
String result = String.format("displaying \tWeather Conditions hPa\n",""); 
result += listWeatherFeature(new WindFormatterStrategy()); 
関連する問題