【问题标题】:Iterator over a snapshot of a filesystem subtree文件系统子树快照上的迭代器
【发布时间】:2012-12-02 08:56:17
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 所以您希望您的迭代器拥有文件系统的快照,这样如果文件在迭代时发生更改,这些更改不会反映在迭代中?例如,您想迭代快照并忽略当前迭代对文件系统的更改?
  • 现在我正在考虑它,也许另一个实体应该负责创建快照,而迭代器只会在其构造函数中接受快照。
  • 你的问题到底是什么?请注意,迭代器通常不是使用构造函数创建的,而是使用可迭代类上的方法创建的。你只需要让这个方法初始化迭代器。
  • 这是有道理的。因此,我宁愿拥有一个 SnapshotFactory,而不是迭代器,它会在给定时间生成文件系统的可迭代快照(例如文件名的链接列表)。对吗?
  • 是的,没错。要么急切地创建快照,要么在第一次在对象上调用 iterator() 时懒惰地创建。此方法可能会引发异常。迭代器本身的 hasNext() 和 next() 方法不会抛出任何东西。

标签: java oop design-patterns iterator


【解决方案1】:

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

HTH

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-18
      • 2011-08-07
      • 2023-04-02
      • 2015-02-05
      • 2021-08-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多