【问题标题】:How to use an interface/something similar to clean up duplicate code in Java如何使用接口/类似的东西来清理 Java 中的重复代码
【发布时间】:2021-04-24 04:10:46
【问题描述】:

我有输出函数,可以将来自不同对象的数据输出到它们对应的文件中。这些函数中的大多数都遵循相同的模式,唯一的区别是所使用的对象以及所使用的对象的固有方法。

我将 '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() 调用,以及在 SubObject1 中具有唯一实现的 getData() 方法和 2.

有没有更好的方法来消除重复代码?

【问题讨论】:

    标签: java oop interface coding-style code-duplication


    【解决方案1】:

    你的问题说得不好,但我会尽量用所提供的信息来回答。

    首先,我会写一个抽象类。

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

    现在我们可以根据需要在许多其他类中实现这个接口。假设你现在有两个。

        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 的子对象,并且可以为子对象创建子对象,依此类推。

    现在,在您的 writer 中,您可以只使用一种方法:

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

    同样,也许这不是您想要的(我觉得返回字符串列表的方式很奇怪),但它至少应该可以帮助您找到正确的解决方案。

    【讨论】:

      【解决方案2】:

      创建一个私有方法

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-26
        • 1970-01-01
        • 1970-01-01
        • 2023-03-14
        • 1970-01-01
        • 2022-12-13
        • 2011-09-16
        • 2014-12-19
        相关资源
        最近更新 更多