如何使用 interface/something 类似于清理 Java 中的重复代码
How to use an interface/something similar to clean up duplicate code in Java
我有输出函数,可以将不同对象的数据输出到它们对应的文件中。这些函数中的大多数都遵循相同的模式,唯一的区别是所使用的对象以及扩展所使用的对象的固有方法。
我将 'obj' 传递给所有写入函数,在每个单独的写入函数中,我们调用不同的 'obj.get...' 函数来获取不同的对象以从中获取数据并输出。
我的输出函数是这样调用的:
for (Object obj : objects) {
writer.writeSubOject1(obj, dir, "subObject1.csv", true);
writer.writeSubOject2(obj, dir, subObject2.csv, true);
....
}
写入函数的代码:
public class Writer{
public void writeSubOject1(Object obj, File dir, String filename, Boolean append) {
ArrayList<SubObject1> subObject1 = obj.getSubObject1();
try {
log.info("writing " + filename + "...");
ArrayList<String[]> so1Data = SubObject1.getData(subObject1);
final File out = CreateFileObject(dir, filename);
writeCsv(so1Data, out, append);
} catch (Exception e) {
log.info("Error in writeSubOject1");
log.error(e);
e.printStackTrace();
}
}
public void writeSubOject2(Object obj, File dir, String filename, Boolean append) {
ArrayList<SubObject2> subObject2 = obj.getSubObject2();
try {
log.info("writing " + filename + "...");
ArrayList<String[]> so2Data = SubObject2.getData(subObject2);
final File out = CreateFileObject(dir, filename);
writeCsv(so2Data, out, append);
} catch (Exception e) {
log.info("Error in writeSubOject2");
log.error(e);
e.printStackTrace();
}
}
}
您可以看到这两种方法之间的唯一区别是 obj.getSubObjectX() 调用和 getData() 方法,它在 SubObject1 和 2 中具有独特的实现。
是否有更好的方法来消除重复代码?
你的问题提得不好,我会根据提供的信息尽量回答。
首先,我会写一篇摘要class。
public abstract class WritableObject {
List<WritableObject> children = new ArrayList<>();
public abstract List<String> getDataAsStringList();
List<WritableObject> getChildren() {
return this.children;
}
public void addChild(WritableObject wo) {
children.add(wo);
}
}
现在我们可以根据需要在任意多的其他 class 中实现此接口。假设您现在有两个。
public class WritableObjectOne extends WritableObject {
@Override
public List<String> getDataAsStringList() {
return Arrays.asList(""); // here the object returns it's String representation
}
}
public class WritableObjectTwo extends WritableObject {
@Override
public List<String> getDataAsStringList() {
return Arrays.asList(""); // here the object returns it's String representation
}
}
现在,最好的部分是您可以随意组合。您可以拥有任何 WritableObject 的 children,并且可以拥有 child 的 children,依此类推。
现在,在您的编写器中,您只能使用一种方法:
public class Writer {
public void writeSubOject(WritableObject obj, File dir, String filename, Boolean append) {
List<WritableObject> children = obj.getChildren();
try {
log.info("writing " + filename + "...");
List<String> data = new ArrayList<>();
for (WritableObject child:children) {
data.addAll(child.getDataAsStringList());
}
final File out = CreateFileObject(dir, filename);
writeCsv(data, out, append);
} catch (Exception e) {
log.info("Error in writeSubOject1");
log.error(e);
e.printStackTrace();
}
}
}
同样,也许这不是您想要的(我觉得返回字符串列表的方式很奇怪),但它至少应该可以帮助您找到正确的解决方案。
创建私有方法
writeSubOject(ArrayList<String[]> soData, File dir, String filename, Boolean append) {
try {
log.info("writing " + filename + "...");
final File out = CreateFileObject(dir, filename);
writeCsv(soData, out, append);
} catch (Exception e) {
log.info("Error in writeSubOject");
log.error(e);
e.printStackTrace();
}
}
然后在你的public方法中
public void writeSubOject1(Object obj, File dir, String filename, Boolean append) {
ArrayList<SubObject1> subObject1 = obj.getSubObject1();
ArrayList<String[]> so1Data = SubObject1.getData(subObject1);
writeSubOject(so1Data,dir,filename,append);
}
public void writeSubOject2(Object obj, File dir, String filename, Boolean append) {
ArrayList<SubObject2> subObject2 = obj.getSubObject2();
ArrayList<String[]> so2Data = SubObject2.getData(subObject2);
writeSubOject(so2Data,dir,filename,append);
}
我有输出函数,可以将不同对象的数据输出到它们对应的文件中。这些函数中的大多数都遵循相同的模式,唯一的区别是所使用的对象以及扩展所使用的对象的固有方法。
我将 'obj' 传递给所有写入函数,在每个单独的写入函数中,我们调用不同的 'obj.get...' 函数来获取不同的对象以从中获取数据并输出。
我的输出函数是这样调用的:
for (Object obj : objects) {
writer.writeSubOject1(obj, dir, "subObject1.csv", true);
writer.writeSubOject2(obj, dir, subObject2.csv, true);
....
}
写入函数的代码:
public class Writer{
public void writeSubOject1(Object obj, File dir, String filename, Boolean append) {
ArrayList<SubObject1> subObject1 = obj.getSubObject1();
try {
log.info("writing " + filename + "...");
ArrayList<String[]> so1Data = SubObject1.getData(subObject1);
final File out = CreateFileObject(dir, filename);
writeCsv(so1Data, out, append);
} catch (Exception e) {
log.info("Error in writeSubOject1");
log.error(e);
e.printStackTrace();
}
}
public void writeSubOject2(Object obj, File dir, String filename, Boolean append) {
ArrayList<SubObject2> subObject2 = obj.getSubObject2();
try {
log.info("writing " + filename + "...");
ArrayList<String[]> so2Data = SubObject2.getData(subObject2);
final File out = CreateFileObject(dir, filename);
writeCsv(so2Data, out, append);
} catch (Exception e) {
log.info("Error in writeSubOject2");
log.error(e);
e.printStackTrace();
}
}
}
您可以看到这两种方法之间的唯一区别是 obj.getSubObjectX() 调用和 getData() 方法,它在 SubObject1 和 2 中具有独特的实现。
是否有更好的方法来消除重复代码?
你的问题提得不好,我会根据提供的信息尽量回答。
首先,我会写一篇摘要class。
public abstract class WritableObject {
List<WritableObject> children = new ArrayList<>();
public abstract List<String> getDataAsStringList();
List<WritableObject> getChildren() {
return this.children;
}
public void addChild(WritableObject wo) {
children.add(wo);
}
}
现在我们可以根据需要在任意多的其他 class 中实现此接口。假设您现在有两个。
public class WritableObjectOne extends WritableObject {
@Override
public List<String> getDataAsStringList() {
return Arrays.asList(""); // here the object returns it's String representation
}
}
public class WritableObjectTwo extends WritableObject {
@Override
public List<String> getDataAsStringList() {
return Arrays.asList(""); // here the object returns it's String representation
}
}
现在,最好的部分是您可以随意组合。您可以拥有任何 WritableObject 的 children,并且可以拥有 child 的 children,依此类推。
现在,在您的编写器中,您只能使用一种方法:
public class Writer {
public void writeSubOject(WritableObject obj, File dir, String filename, Boolean append) {
List<WritableObject> children = obj.getChildren();
try {
log.info("writing " + filename + "...");
List<String> data = new ArrayList<>();
for (WritableObject child:children) {
data.addAll(child.getDataAsStringList());
}
final File out = CreateFileObject(dir, filename);
writeCsv(data, out, append);
} catch (Exception e) {
log.info("Error in writeSubOject1");
log.error(e);
e.printStackTrace();
}
}
}
同样,也许这不是您想要的(我觉得返回字符串列表的方式很奇怪),但它至少应该可以帮助您找到正确的解决方案。
创建私有方法
writeSubOject(ArrayList<String[]> soData, File dir, String filename, Boolean append) {
try {
log.info("writing " + filename + "...");
final File out = CreateFileObject(dir, filename);
writeCsv(soData, out, append);
} catch (Exception e) {
log.info("Error in writeSubOject");
log.error(e);
e.printStackTrace();
}
}
然后在你的public方法中
public void writeSubOject1(Object obj, File dir, String filename, Boolean append) {
ArrayList<SubObject1> subObject1 = obj.getSubObject1();
ArrayList<String[]> so1Data = SubObject1.getData(subObject1);
writeSubOject(so1Data,dir,filename,append);
}
public void writeSubOject2(Object obj, File dir, String filename, Boolean append) {
ArrayList<SubObject2> subObject2 = obj.getSubObject2();
ArrayList<String[]> so2Data = SubObject2.getData(subObject2);
writeSubOject(so2Data,dir,filename,append);
}