我有一些数据对象,例如Task
,Resource
等。
这些对象包含域数据,例如
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重复相同的操作。 如您所见,我正在为每个域对象复制相同的代码。唯一不同的是实际的域对象。这些方法对每个域对象执行完全相同的操作。
我的问题是;如果我要重构这些方法并分别编写一个方法来应用于每个域对象,那么我最好的选择是什么。
答案 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)