Java 软件设计 - 循环、对象创建与修改变量。内存、性能和可靠性比较



假设我们正在尝试在java中构建一个文档扫描仪类,该类接受1个输入参数,即日志路径(例如。C:\document\text1.txt)。根据性能/内存/模块化,您更喜欢以下哪种实现?

ArrayList<String> fileListArray = new ArrayList<String>();
fileListArray.add("C:\document\text1.txt");
fileListArray.add("C:\document\text2.txt");
.
.
.

//Implementation A
for(int i =0, j = fileListArray.size(); i < j; i++){
    MyDocumentScanner ds = new MyDocumentScanner(fileListArray.get(i));
    ds.scanDocument(); 
    ds.resultOutput();
}
//Implementation B
MyDocumentScanner ds = new MyDocumentScanner();
for(int i=0, j=fileListArray.size(); i < j; i++){
    ds.setDocPath(fileListArray.get(i));
    ds.scanDocument(); 
    ds.resultOutput(); 
}

就个人而言,由于它的封装,我更喜欢 A,但由于创建多个实例,它似乎需要更多的内存使用。我很好奇这是否有答案,或者这是另一个"取决于情况/情况"的困境?

虽然这显然是基于意见的,但我会尝试一个答案来表达我的观点。

你接近A要好得多。您的文档扫描仪显然会处理文件。这应该在施工时设置并保存在实例字段中。因此,每个方法都可以引用此字段。此外,构造函数可以对文件引用进行一些检查(null 检查、存在等)。

您的方法B有两个非常严重的缺点:

  1. 构建文档扫描仪后,客户可以轻松调用所有方法。如果之前没有设置任何文件,则必须使用IllegalStateException来处理该"非法状态"。因此,此方法增加了该类的代码和复杂性。

  2. 客户端似乎应该或可以执行一系列方法调用。在此类系列的中间使用完全不同的文件再次调用文件设置方法很容易,从而破坏整个扫描功能。为避免这种情况,您的资源库(对于文件)应该记住文件是否已设置。这几乎自动导致接近A。

关于对象的创建:现代JVM在创建对象方面确实非常快。通常,没有可衡量的性能开销。处理时间(此处:扫描)通常要长得多。

如果您不需要多个DocumentScanner实例共存,我认为在循环的每次迭代中创建新实例是没有意义的。它只是为垃圾回收器创建工作,垃圾回收器必须释放每个实例。

如果数组的长度很小,则选择哪种实现没有太大区别,但对于大型数组,实现 B 在内存(GC 尚未释放的创建实例更少)和 CPU(GC 的工作量更少)方面效率更高。

您是在实现DocumentScanner还是使用现有类?

如果是后者,并且它旨在能够连续解析多个文档,则可以像变体 B 中那样重用该对象。

但是,如果您正在设计 DocumentScanner ,我建议您将其设计为处理单个文档,甚至没有setDocPath方法。这导致该类中的可变状态减少,从而使其设计变得更加容易。此外,使用该类的实例变得不那么容易出错。

至于性能,除非实例化DocumentScanner正在做大量工作(例如实例化许多其他对象),否则不会有可衡量的差异。在 Java 中实例化和释放对象是非常便宜的,如果由于代垃圾回收器,它们只在短时间内使用。

最新更新