我需要在Java中的文件系统子树上开发一个迭代器。在迭代仍在进行时,文件系统的状态可能会发生变化(例如,创建和删除新文件夹和文件)。因此,迭代器应首先捕获层次结构的快照(例如,抓取树并保存找到的所有文件的名称),然后迭代快照。
我想知道是否将代码放入迭代器的构造函数中是否是一个好主意。另一种方法是为其指定一个speciall方法(名为{{1 }})。
迭代子树的大小和深度可能会非常大,因此缓存将非常耗时。而且,它可能抛出IOExceptions(我仍然不确定在Java中从构造函数中抛出异常是否是一个好的设计实践)。
另一方面,创建一个初始化迭代器的专用方法意味着客户端代码不能将迭代器简单地用作Iterator接口的实现。
客户端代码还负责在遍历之前调用init方法。我可以让init
/ hasNext
方法首先确保迭代器已经初始化,如果没有,请从它们内部调用next
方法。但这意味着对这些方法的第一次调用将明显慢于下一次调用,而客户端没有任何理由可见。
答案 0 :(得分:0)
在构造函数中创建缓存应该没问题。关于耗时的部分,您需要根据您将如何使用迭代器来决定。如果客户端无法迭代直到缓存完成,那么构建器或init方法是否需要时间并不重要,这是一个同步阻塞操作。
如果你可以在缓存完成之前开始迭代,你可以启动一个执行缓存的线程,但是你需要覆盖hasNext()来考虑这个,它将是hasNext()或者next ()谁在等待。
答案 1 :(得分:0)
正如你在评论中所说,我会将责任分为两类:一类用于获取文件系统的快照(例如FileSystemSnapshot
),另一类用于迭代它。根据您需要的灵活性,您可以在迭代器的构造函数中创建FileSystemSnapshot
实例,或将其作为构造函数参数传递。从第一个方向开始,客户可以更灵活地配置迭代器,如果您计划采用不同的策略来获取文件系统快照,则可能很有价值。它也更适合单元测试,因为它很容易创建mocks or stubs。但是,您强制客户端了解遍历详细信息(即在遍历文件系统之前必须缓存该文件系统)。使用第二种方法从客户端隐藏了这个实现细节,但是不太灵活,而且测试起来有点棘手(这里你可以定义一个createFileSystemSnapshot()
方法,然后模拟该方法为你的测试返回一个不同的实例)。您可能还想查看dependency injection模式。
HTH