How to use an interface/something similar to clean up duplicate code in Java

I have output functions that output data from different objects to their corresponding files. Most of these functions follow the same pattern, the only differences are the objects being used and by extension, the object’s inherent methods being used.

I pass in ‘obj’ to all the write functions, and in each individual write function we call different ‘obj.get…’ functions to get different objects to grab data from to output.

My output functions are called like so:

for (Object obj : objects) {
    writer.writeSubOject1(obj, dir, "subObject1.csv", true);
    writer.writeSubOject2(obj, dir, subObject2.csv, true);
    ....
}

Code for the write functions:

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();
    }
}
}

You can see that the only differences between the two methods is the obj.getSubObjectX() call, and the getData() method which has a unique implementation in SubObject1 and 2.

Is there a better way to do this to get rid of duplicate code?

Answer

make a private method

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();
    }
}

then in your public methods

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);
}

Leave a Reply

Your email address will not be published. Required fields are marked *