我有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 :(得分: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());