如何重构这些方法?

时间:2011-12-03 23:47:30

标签: java

我有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;

}

我怎么能重构它们?

3 个答案:

答案 0 :(得分:4)

我发现两种方法在至少两点之间存在差异:你有不同的标题,你有不同的格式。在泛型方法中,可以通过传递String参数来简单地处理不同的头文件。第二个问题可以通过包含一个参数来解决,该参数指示如何格式化字符串,并在相应的方法中处理它。

如果你想要一个非常通用的方法,你可以通过一个接口来实现。像这样:

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

还有一个想法:你可以结合我的两个建议。您为该方法创建一个参数,该参数不仅仅是一个接口,而是一个实现此接口的枚举。在枚举声明中,您为每个常量实现了formatWeather()方法。这将是一个非常面向对象的设计。

答案 1 :(得分:2)

如果我正确地阅读了您的代码,那么这些方法之间的唯一区别似乎就是如何处理循环中的Weather对象。在这种情况下,您只需附加字符串。可能值得考虑一种方法来进行循环,并让它将实际的“我该怎么做”委托给你传入的对象。

例如,您可以创建一个界面来表示“做某事”部分...

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

然后,重新实现您的天气循环代码以获取其中一个新对象......

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中。只需在接口中添加一个方法即可返回标头并在实现类中实现它。

答案 2 :(得分:0)

建议:使用Strategy模式即时定义格式策略

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());