需要帮助重构一些重复的Java代码。接口或泛型或其他一些解决方案?

时间:2013-12-13 17:28:23

标签: java generics refactoring

我有一些数据对象,例如TaskResource等。

这些对象包含域数据,例如

public class Task{
   private int Id;
   private String taskName;
.......
  //getters and setters here

//in addition they have a special method dynamically to get values i.e. There is a reason for this

         public static String runGetter(Task task, String getter) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
                for (Method method : task.getClass().getMethods()) {
                    if (method.getName().toLowerCase().equalsIgnoreCase(getter.toLowerCase())) {
                        if (method.getReturnType().isPrimitive()) {
                            StringBuilder sb = new StringBuilder();
                            sb.append(method.invoke(task));
                            return sb.toString();
                        }
                        if (method.invoke(task) != null) {
                            return method.invoke(task).toString();
                        }
                    }
                }

                return null;
            }

        }
}

现在我有一些方法可以获取这些对象并将它们写入流

e.g。

public class WriterUtil{

    public void write(Task task, File outputFile){
    //write the task object out.

}

public void write(资源资源,文件outputFile){             //写出资源对象             }

        ....

}

write方法调用另一种方法从对象中获取数据,如下所示。 (是的,它可以提高效率,但它不是我问题的核心)

public class WriterUtil {
.....

    public static String extractLine(Task task, LinkedHashMap<String, String> columns, String delimiter) throws IllegalAccessException,
                IllegalArgumentException, InvocationTargetException {
            StringBuilder sb = new StringBuilder();
            Iterator<String> itr = columns.keySet().iterator();
            while (itr.hasNext()) {
                String getter = "get" + itr.next();
                String value = Task.runGetter(task, getter);
                if (value == null)
                    value = "";
                sb.append(value + delimiter + " ");
            }
            return sb.toString().substring(0, sb.lastIndexOf(delimiter)).trim();
        }
......


}

我的主要问题是,鉴于上述情况,我发现自己为每个域对象编写相同的相同代码,例如。

public void write(任务任务,文件outputFile) public void write(资源资源,文件outputFile) //等....

我对extractLine重复相同的操作。 如您所见,我正在为每个域对象复制相同的代码。唯一不同的是实际的域对象。这些方法对每个域对象执行完全相同的操作。

我的问题是;如果我要重构这些方法并分别编写一个方法来应用于每个域对象,那么我最好的选择是什么。

  1. 我应该让域对象实现接口吗?这看起来相当麻烦,我不确定这是正确的行动方案。
  2. 我可以使用泛型吗?我希望这可能是最好的做法,但我对如何进行一般化(这是一个词?)我的Domain Objects和这些常用方法的经验非常有限。有人可以重新编写我的上述代码,以便他们如何修改它们的通用名称吗?
  3. 我有第三种选择吗?

2 个答案:

答案 0 :(得分:0)

您需要使用界面;这里不能使用泛型(你可以在C ++中使用模板,但不能在Java中)。

如果您不希望对象实现该接口,则可以为每个域类创建辅助对象;这些辅助对象将实现具有extractLine()函数的接口:

class TaskExtractLine implements IExtractLine
{
  public TaskExtractLine(Task task)
  {
    this.task = task;
  }

  public String extractLine(LinkedHashMap<String, String> columns, String delimiter)
      throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
  {
    return WriterUtil.extractLine(task, columns, delimiter);
  }

  private Task task;
}

然后你将拥有这样的写函数:public void write(IExtractLine extractLineHelper, File outputFile)并将其称为:write(new TaskExtractLine(task), outputFile)

答案 1 :(得分:0)

将反射代码移动到实用程序类型中,并将签名更改为:

public static String runGetter(Object bean, String getter)

方法内部根本不使用Task类型。

同样,这里需要Task类型的唯一原因是因为另一个调用需要它:

public static String extractLine(Object bean, Map<String, String> columns,
                                                                String delimiter)