2013-08-16 27 views
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); 

在我看来,选项2对我来说很好,但唯一的问题,我与它,是checkIfPathExists)“般的状态检查法‘(’冗余/不必要的呼叫。理想情况下,这不是getPath()应该做的。它应该只是返回路径。

  1. 哪一个更好的实现选项1或选项2?

  2. 如果option2是一个更好的选择,那么它会是一个更好的设计选择,不添加'checkIfPathExists'作为公共接口?为了提出一个更通用的状态检查方法,像'hasNext()'这样的检查方法,如果不强制执行似乎是不必要的。即使遍历一个列表,我们可以得到列表的大小,并使用for循环,直到我< =大小,并从来没有使用hasNext()。 简而言之 - 如果不执行状态检查函数,则使用状态检查函数是什么?

  3. 执行状态检查方法的任何“真实”示例?意思是说,不要将它们先前的结果称为异常?

+0

我同意你的意见。我没有看到需要额外的函数调用'checkIfPathExists()'。 – Clocks

+0

api不能被修改的意义是什么?这似乎与你的问题无关,或使你的问题毫无意义。 –

回答

0

无论是否有checkIfExistshasNext功能只存在于“保护”的号召,另一个函数实际上取决于关于受保护职能的成本和后果。

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

IteratorhasNext,对于这部分原因的情况是调用next有后果和未知的成本(可以使用网络连接进行迭代从数组到一个单向链表的东西什么)。一旦调用next,您也无法返回,因此在处理当前元素的逻辑根据是否存在下一个元素而变化的情况下,Iterator需要支持它。

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

要回答你的问题直接选项2将通常首选,因为它是更期望的,并且不需要额外的代码的复杂性,以验证调用序列。首先调用checkIfPathExists的优点(如果存在的话)的文档将足以阻止对该选项的任何顾虑。

2

我不知道什么样的API是这样的,但我不认为这是一个特殊的情况下,一个路径没有两个顶点之间存在,所以抛出和异常似乎并不成为一个好主意。

如果您正在争创minimal interface那么你可以从你的API下降boolean checkIfPathExists(source, destination);并利用番石榴的Optional类为getPath(source, destination);返回值来表示可能没有两个顶点之间存在路径。请记住,您必须区分不存在的路径和零长度路径。另一方面,如果你想提供一个human interface,那么你可以保留boolean checkIfPathExists(source, destination);作为一种方便的方法来检查顶点之间是否存在路径而不强制客户端实际检索它(这甚至可以提供一些性能空间优化)。请注意,这只是一个方便方法,它不是强制性的在getPath之前调用它,我认为这不会是一个好设计,因为它会导致sequential coupling。最后,如果你不能决定哪个更好,那么坚持最小的API,以后再扩展更容易。记住由Joshua布洛赫的黄金法则:

有疑问时离开它

相关问题