Answers:
我认为您在正确的轨道上。抛出,捕获或记录所有可能抛出的异常都没有多大意义。有时产品严格度要求更高程度的例外采用和记录(例如,系统的某些安全关键方面)。
使用合同概念来确定特别是下游呼叫者(例如,类似于公共或受保护成员的任何呼叫者)的前提条件(例如,类似公共或受保护成员的条件)的防御性更高的策略通常会更有效,更灵活。这不仅适用于实现,而且适用于文档。如果开发人员知道预期的结果,那么他们更有可能遵守规则,而不太可能混淆或滥用您编写的代码。
应该记录的一些常见事物包括空参数的情况。通常,使用它们会导致某种结果,使结果达到通常无法预期的程度,但由于各种原因(有时出于灵活性)而被允许和使用。作为具有允许空值或其他特殊的非有理值(例如负时间或负数量)的参数的成员的消费者,我希望可以看到它们并加以说明。
对于非null参数,作为公共或受保护成员的使用者,我想知道不允许null。我想知道给定上下文中的有效值范围是多少。我想知道使用超出正常范围但在其他调用上下文中有效的值的后果(例如,该类型的值通常对任何操作均有效,但不适用于此操作-就像布尔参数那样)不要期望false为有效值。
就平台或其他众所周知的界面而言,我认为您不必费力地记录下来。但是,由于您作为开发人员有机会从任何平台指南中更改实现,因此请注意该指南遵循的价值。
特定于IDisposable,此接口的实现通常提供了一种替代方法,该方法比显式处理过程更可取。在这些情况下,请突出显示首选方法,并注意不要采用显式处理。
performReadCommand(ICommand cmd, int replySizeBytes)
-您是否希望cmd接受null或replySizeBytes为负值?只有在实际允许这些值的情况下,才需要IMO文档,并且您可能应该解决0对于ReplySizeBytes是否有效。
这是我自己的想法。请注意,我不太确定这是最好的方法,这就是为什么我首先提出这个问题的原因。
据我了解,立即调用者实际处理编程错误异常没有什么意义,他应该确保满足先决条件。只有位于任务边界的“外部”异常处理程序才能捕获它们,因此,如果任务失败,它们可以使系统保持运行。
为了确保客户端代码可以干净地捕获“失败”异常而不会错误地捕获错误异常,我现在为所有失败异常创建自己的异常类,并在引发它们的方法中记录它们。我会让他们在Java中检查异常。
直到最近,我还尝试记录一个方法可能引发的所有异常,但是有时会创建一个不希望看到的列表,该列表需要在调用链的每个方法中记录下来,直到您可以证明不会发生错误为止。相反,我现在在摘要/参数描述中记录前提条件,甚至不提及如果不满足前提条件会发生什么。这样的想法是,人们无论如何都不应试图明确地捕获这些异常,因此无需记录其类型。
为了记录前提条件,陈述显而易见的条件只会造成不必要的混乱-如果将null传递给方法没有明显的意义,则调用者无论如何传递null都必须期望异常,即使未记录也是如此。对于ObjectDisposedException而言,情况也是如此-该接口的使用是如此广泛,以至于调用Dispose的人将意识到确保没有人继续使用该对象的责任。
甚至Java也不“记录”所有异常。尽管要求throw
在throws
子句中提及每个n个异常,但是任何代码行都可以抛出a RuntimeException
而不需要在方法签名中声明它。
标准的方法是使用Java方法。编程错误应该是未经检查的异常,并且不应被捕获以确保快速失败。合同错误是检查过的异常,应由客户适当处理。