2010-02-03 125 views
4

我怀疑是否存在明确的答案,但我对这个主题的不同意见很感兴趣。因此,一个共同的维基。当您的方法失败,但成功...您会返回失败还是成功?

您正在设计一种方法。它有一个目的,这就是为什么你设计它的原因。呼叫者使用你的方法,但方法失败了,但是,你看,最终的目的是尽可能地消除方法的存在 - 这要归功于你选择的超出你的控制范围或某种魔法的外部环境。您是否将这种情况报告给主叫方是失败还是成功?

让我们选一个简单的例子。您正在编写DeleteFile函数。它采用文件路径并删除文件。有人调用这个函数,提供一个路径。该函数查找文件,但它不存在。这不是一个权限问题或什么的,该文件是真正失踪。也许另一个进程在微秒之前删除它,也许它从来没有存在过。该函数未能完成其任务,因此它必须报告失败......但用户调用此函数的唯一原因是确保文件不存在,并且,瞧,它不会,所以它是一个成功。

我预计答案就像“只是在你的返回值中更加冗长”,我很乐意返回一个详细的结果作为补充信息,但是你会返回什么(以及为什么)作为主要成功标志功能,成功还是失败?用BUT_DOES_NOT_EXIST_ANYWAY的附加标志是否为FALSE,还是用BUT_THANK_SOMEONE_ELSE标志为TRUE?

编辑

请不要给出答案,仅适用于上面的例子。我总是在询问一些情况,包括何时该方法没有参数,或者出于某种其他原因无法以错误的方式调用它。

回答

13

当新的程序员学习如何编写功能,术语前提后置经常介绍。先决条件是必须满足您的方法才能正常工作的假设。后置条件保证了你的方法在执行后对系统的状态作出了保证。

我认为调用deleteFile方法时预期的合理前提条件是该文件当前存在。如果不满足前提条件,则即使已经以意外的迂回方式实现了后置条件,该方法仍应该失败。现在

,如果你的方法被称为deleteFileIfExists,这是一个不同的故事。您没有对该方法施加如此严格的先决条件。

7

遵循最少惊喜的原则,抛出异常。

我想到的方式是这样的:如果我正在编写代码并在我的代码中包含一个错误,它将错误的路径传递给DeleteFile函数,导致路径如此不正确以至于它永远不会存在,我期望DeleteFile抛出,以表明我做错了什么。

如果你想要的话,你可以创建一个接受一个名为ThrowOnFileNotExist或者其他参数的重载,如果设置为false,它不会抛出这种情况。但我认为这将是罕见的异常情况。

+0

非常好点但我更感兴趣的情况下提供了一个无效参数的方法是不是一个问题一样,想象一种根本没有参数的方法 – GSerg 2010-02-03 22:23:56

4

这就是例外情况。

抛出新FileDoesNotExistException

3

如果你开始失败,并成功地这样做,你做了什么?

我认为这是由客户决定要做什么。如果你的函数被要求删除一个不存在的文件,抛出一个异常。然后,客户端可以捕获该异常并确定该文件是否存在或已成功删除,最终结果是相同的,并且可以正常进行。

或者,如果文件丢失是一个预期的可能性,即也不例外,你可以只返回一个失败状态将调用者可以随意忽略:)这再次离开的决定给客户端。

在任何一种情况下,如果遵循函数应该做的一件事情并且做得很好的原则,客户端可以以任何适当的方式将函数调用串在一起,而成功或失败变得更加精细晶。

你不应该做的是返回成功,如果函数没有成功完成。最终结果是否巧合相同并不重要。这样疯狂的谎言。

0

函数应该抛出一个异常(或者返回一个失败值,不管)。但是,用户应该可能会看到成功。

IOW,调用函数的程序员应该知道事实。但用户界面向用户呈现的内容取决于整体功能,我假定目标用户。

要利用你的“删除文件”的例子 - 在正常情况下我希望您的应用程序只是从列表中删除,或任何文件,并继续前进 - 让用户看到该文件已被删除;他们可能不在乎它是如何发生的。

(“正常情况下”,因为在一些应用程序,它可能是很重要的。)

+0

用户选择一个文件并说delete,程序员调用DeleteFile(file),并通过从列表中删除该文件来处理FileDoesNotExist异常? – 2010-02-05 01:43:46

+0

广义上讲,我的意思是,调用函数的程序员可能会关心差异,即使他的程序的用户没有。 理想情况下,没有函数应该假定它知道调用它的代码的任何内容,也许函数正在被使用在一家公司完全不同的一段代码与它所写的代码完全不同! – Shadowfirebird 2010-02-05 10:01:36

1

你举的例子是三元布尔完美的一个:True/False/FileNotFound

enum Bool 
{ 
    True, 
    False, 
    FileNotFound 
}; 

UPDATE
玩笑归玩笑。如果该方法无法执行它的功能,那么它应该有一个适合这种情况的返回码(或抛出的异常)。如果最终结果是相同的,则该方法无关紧要;尽管它可能是该方法的调用者。

我宁愿避免抛出异常,而是维护返回码。恕我直言,异常类型存在代码无法处理的情况。你的示例方法足够小,只需返回False就足够了。这将取决于调用代码来确定原因。

有很多理由喜欢的DeleteFile一个简单的方法可能会失败。文件不存在,您没有安全权限,文件被锁定,文件系统被阻止等等。每个文件都应该有自己特定的返回失败代码。

然后,它需要调用代码来决定“哦文件不存在,没关系”。或者,“你是什么意思,我没有权利?!?中止!“

的观点是:。不要除非该方法能够实际执行返回true

+0

嗯......你怎么用一点代表三元状态?或者就此事发表评论? – Duncan 2010-02-05 00:28:57

+0

请点击链接。在一些圈子里,这是一个很长的笑话。 – NotMe 2010-02-05 01:14:14