2

假设我们有一个 API。

interface Graph {
    boolean checkIfPathExists(source, destination);
    List<Integer> getPath(source, destination);
}

以下哪一项是最佳/推荐的实施方式。

选项 1:强制检查以验证路径是否存在。如果之前未调用 checkPath,则抛出异常。

Graph g = new GraphImpl(graph);
if (g.checkIfPathExists(s, d)) {
   List path = g.getPath(s, d);
}

选项 2:不强制执行功能序列。如果调用 getPath,则让 getPath() 内部调用 checkIfPathExists() 并在 checkIfPathExists() 返回 false 时返回空集合;

Graph g = new GraphImpl(graph);
List path = g.getPath(s, d);

在我看来,Option2 对我来说看起来不错,但我唯一遇到的问题是对'checkIfPathExists()'之类的状态检查方法的冗余/不必要的调用。理想情况下,这不是 getPath() 应该做的。它应该只是返回路径。

  1. 哪个是更好的实现 option1 或 option2 ?

  2. 如果 option2 是一个更好的选择,那么根本不添加“checkIfPathExists”作为公共接口会是一个更好的设计选择吗?为了使问题更通用的状态检查方法看起来像“hasNext()”,如果没有强制执行似乎是不必要的。即使遍历一个列表,我们也可以获得列表的大小并使用 for 循环直到 i <= size,并且根本不使用 hasNext()。简而言之 - 如果不强制执行状态检查功能,它们有什么用?

  3. 任何强制执行状态检查方法的“现实生活”示例?意思是,不先调用它们会导致异常?

4

2 回答 2

2

我不知道这是一个什么样的API,但我不认为两个顶点之间不存在路径是一种例外情况,因此抛出和异常似乎不是一个好主意。

如果您正在争取一个最小的接口,那么您可以从您的 API 中删除boolean checkIfPathExists(source, destination);并使用 Guava 的Optional类作为返回值getPath(source, destination);来指示两个顶点之间可能不存在路径。请记住,您必须区分不存在的路径和零长度路径。

另一方面,如果您想提供人机界面,那么您可以保留boolean checkIfPathExists(source, destination);作为一种方便的方法来检查顶点之间是否存在路径,而无需强制客户端实际检索它(这甚至可能为性能优化提供一些空间)。请注意,这只是一种方便的方法,之前并不强制调用它getPath,我认为这甚至不是一个好的设计,因为它会导致顺序耦合

最后,如果你不能决定哪个更好,那就坚持使用最少的 API,以后扩展更容易。记住 Joshua Bloch 的黄金法则:

如有疑问,请忽略它

于 2013-08-16T21:36:23.677 回答
0

是否具有仅用于“保护”对另一个函数的调用的checkIfExistsorhasNext函数实际上取决于受保护函数的成本和后果。

如果getPath非常昂贵并且checkIfPathExists非常快,那么同时具有这两种功能是有意义的。checkIfPathExists但是,在 之前强制调用相同的参数getPath是不寻常的并且似乎没有必要,因为如果您可以将该机制放入,那么您还可以缓存其结果,因此不需要实际强制执行它getPath,只需使用缓存如果它是可用或执行呼叫。

Iteratorwith的情况下hasNext,部分原因是调用会next产生后果和未知的成本(可能是使用网络连接迭代从数组到单链表的任何东西)。一旦next被调用,您也无法返回,因此在处理当前元素的逻辑根据是否存在下一个元素而发生变化的情况下,迭代器需要支持它。

如果您特别担心性能,那么您可以提供两种方法,一种假设路径确实存在(checkIfPathExists已调用并返回 true),因此不需要执行存在检查,另一种不做这样的假设并调用checkIfPathExists在搜索之前。在 javadoc 中适当地记录方法,用户通常会正确使用它们。

要直接回答您的问题,通常会首选选项 2,因为它更符合预期,并且不需要额外的代码复杂性来验证调用顺序。规定首先调用的优点(如果存在)的文档checkIfPathExists足以解决此选项的任何问题。

于 2013-08-16T21:55:21.273 回答