方法设计决策;何时抛出异常?

时间:2012-03-26 15:34:48

标签: exception

假设我有一个方法必须返回一个对象(比如从数据库层),并将一些关于请求对象的信息作为输入。

在正常情况下,该方法应该返回该对象。但是如果调用者没有满足方法的前提条件会发生什么呢?我该如何(该方法的代码编写者)通知调用者?

以我应该从数据库返回有关用户信息的情况为例,我将用户名和密码作为输入。在正常情况下,我应该返回User对象。但是,如果用户名和密码为空,如果它们不匹配,如果密码太短,该怎么办?如何通知调用者究竟是什么问题? 通常我会抛出异常,但在这里 - When to throw an exception?被认为是一个坏主意。 我应该在User中放置errorDetail字段,还是创建方法checkInputData或getErrorStatus ...

3 个答案:

答案 0 :(得分:1)

在这种情况下抛出异常听起来是完全合理的。该方法应该只做一件事而且只做一件事,就是尝试从数据库中获取用户记录。如果先决条件失败,请放弃。如果数据库出错,请放弃。如果找不到用户,请放弃。让调用代码处理后果。

异常是方法的完全可接受的退出路径。

在前提条件的情况下,解决这个问题不是方法的责任。这是主叫代码的责任。所以抛出某种ArgumentException并让调用代码处理它。

如果出现数据库错误,请捕获它并抛出自定义异常(类似于InfrastructureFailed异常),以便应用程序进行相应处理。基本上,应用程序需要告诉用户存在技术问题,请稍后再试。

在没有找到用户的情况下,这听起来像登录失败。抛出某种SecurityException并让调用应用程序通过通知用户登录失败来处理它。 (不要更具体。例如,不要告诉用户用户名是好的,但密码是坏的。这给恶意用户提供了比你想要的更多的信息。只是说登录失败,没有更。)

您还提到了密码太短的情况。我想这是应该在它到达这一点之前验证的东西。在这种情况下,在该方法的输入检查下会出现这种情况。所以前提条件失败了,方法甚至都没有尝试进入数据库。但是“密码太短”在登录提示时告诉用户可能不是一个好错误。相反,这是因为他们试图创建密码。

您不应该做的一件事是返回null或空的用户对象或类似的东西。这使得调用代码有责任检查是否存在错误。例外是通知调用代码错误的完全有效的方法。返回的“魔术对象”就像代码中的任何其他“魔术字符串”一样,但更糟糕的是因为它从方法泄漏到其他代码中。

现在,当然,这并不总是一个完整的规则。这取决于应用程序的结构。例如,如果这是一个Web服务或某种其他类型的请求/响应系统,那么您可能希望有一个标准响应对象来指示失败。但是,这假定了该方法的一些应用程序上下文。在这种情况下,你可能 仍然在处理多种方法。内部的(域逻辑方法)将抛出异常,外部的(应用程序UX感知方法)将捕获异常并为UI创建适当的非null响应。

如何处理异常取决于应用程序的逻辑结构。但抛出捕获异常(请记住,“捕获”与有意义的“处理”不同)是完全可以接受的行为。

答案 1 :(得分:0)

返回某种哨兵价值是否有意义?如果是这样,请考虑使用它。否则,为什么不抛出异常?

答案 2 :(得分:0)

我会返回一个包含用户的对象(错误情况下为null),成功标志(错误时为false)和作为验证消息的字符串列表(出错时,列表它失败的原因)。

在用户对象上添加errorDetail字段没有意义,因为它实际上不是用户对象的属性。它只是该方法返回数据的一部分。此路径导致具有混淆属性的对象仅用于某些方法。