首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何重构这些方法?

如何重构这些方法?
EN

Stack Overflow用户
提问于 2011-12-04 07:47:30
回答 3查看 132关注 0票数 1

我有4个基本相似的方法,但我不知道如何重构它们

代码语言:javascript
复制
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;

}

我如何重构它们?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-12-04 07:56:13

我至少在两点上看到了这两种方法的不同:你有不同的头,你有不同的格式。在泛型方法中,可以简单地通过传递一个字符串参数来处理不同的标头。第二个问题可以通过包含一个参数来解决,该参数指示如何格式化字符串,您可以在您的方法中相应地处理此问题。

如果你想要一个真正通用的方法,你可以通过一个接口来实现。如下所示:

代码语言:javascript
复制
interface WeatherFormatter {
    String formatWeather(Weather weather);
}

您的泛型方法:

代码语言:javascript
复制
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;
}

你可以这样调用你的泛型方法:

代码语言:javascript
复制
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()方法。这将是一个非常面向对象的设计。

票数 4
EN

Stack Overflow用户

发布于 2011-12-04 07:57:48

如果我没看错您的代码,那么这两个方法之间的唯一区别似乎就是如何处理循环中的Weather对象。在本例中,您只是附加了String。可能值得考虑一种方法来做循环,并让它将实际的“我用这个做什么”委托给您传递的对象。

例如,您可以创建一个接口来表示“做某事”部分……

代码语言:javascript
复制
public Interface WeatherWork {
    public String formatWeatherString(Weather weather);
}

并为您想要的每种类型的输出实现一次...

代码语言:javascript
复制
public class WindWorker implements WeatherWork {
   public String formatWeatherString(Weather weather) {
      return String.format("%s\t\t%s\n",formatter.format(weather.getCalculatedDate()) , weather.getConditions());
   }
}

然后,重新实现您的天气循环代码以获取这些新对象之一……

代码语言:javascript
复制
public String listWind() {
   return formatWeather(new WindWorker());
}

而formatWeather()将执行循环...

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2011-12-04 08:02:28

建议:使用Strategy模式动态定义格式化策略

代码语言:javascript
复制
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());
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8371990

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档