0

我需要在 Java 中的文件系统子树上开发一个迭代器。当迭代仍在进行时,文件系统的状态可能会发生变化(例如,创建和删除新文件夹和文件)。因此,迭代器应该首先捕获层次结构的快照(例如爬取树并将找到的所有文件的名称保存到列表中),然后迭代快照。

我想知道将创建缓存的代码放入迭代器的构造函数中是否是个好主意。另一种方法是为此指定一个特殊的方法(命名init)。

迭代子树的大小和深度可能会变得非常大,因此缓存会很耗时。此外,它可能会抛出 IOExceptions(我仍然不确定从 Java 的构造函数中抛出异常是否是一种好的设计实践)。

另一方面,创建一个专用的方法来初始化迭代器意味着客户端代码不能将迭代器用作迭代器接口的简单实现。

客户端代码还将负责在遍历之前调用 init 方法。我可以让hasNext/next方法首先确保迭代器已初始化,如果没有,init则从其中调用该方法。但这意味着对这些方法的第一次调用将比下一次调用慢得多,而客户端没有任何可见的原因。

4

2 回答 2

0

正如您在评论中所说,我将把职责分成两个类:一个用于获取文件系统的快照(例如FileSystemSnapshot),另一个用于迭代它。根据您需要的灵活性,您可以FileSystemSnapshot在迭代器的构造函数中创建实例或将其作为构造函数参数传递。朝着第一个方向前进可以让客户端更灵活地配置迭代器,并且如果您计划使用不同的策略来获取文件系统快照,这将是很有价值的。它也更适合单元测试,因为它很容易创建模拟或存根. 但是,您强制客户端了解遍历细节(即文件系统必须在遍历之前被缓存)。使用第二种方法对客户端隐藏了这个实现细节,但不太灵活并且测试起来有点棘手(在这里您可以定义一个createFileSystemSnapshot()方法,然后模拟该方法以返回不同的测试实例)。您可能还想检查依赖注入模式。

高温高压

于 2012-12-14T11:38:41.933 回答
0

在构造函数中创建缓存应该没问题。关于其中耗时的部分,您需要根据您将如何使用迭代器来决定。如果客户端在缓存完成之前无法迭代,无论是构造函数还是init方法都需要时间,这是一个同步阻塞操作。

如果您可以在缓存完成之前开始迭代,您可以启动一个执行缓存的线程,但您需要覆盖 hasNext() 以考虑到这一点,它将是 hasNext() 或 next() 谁等待。

于 2012-12-14T11:21:44.257 回答