4

我和我的朋友发生了争执。

他告诉我这段代码:

method SetBalance(balance) {
    if (balance > 0) {
        this.balance = balance;
        return true;
    }
    return false;
}

比这个更好:

method SetBalance(balance) {
    if (balance < 0) {
        throw new InvalidArgumentException("Balance couldn't be negative")
    }
    this.balance = balance; 
}

我的问题是:“哪种方法更适合验证?” 为什么?

谢谢你。

4

6 回答 6

6

啊。返回状态与异常。

我更喜欢抛出异常,因为你不能真正忽略异常。程序要么崩溃,要么你必须明确地捕捉和处理它。

您可以忽略退货状态。

此外,这不是现代编程中存在异常的原因吗?处理,嗯......异常(余额<= 0,不应该发生的事情)。

于 2012-08-10T08:07:35.230 回答
1

返回值很容易被忽略。在这里,您有明显的编码错误,因此请大声崩溃。我什至会停止/段错误/停止程序 - 仍然可能会捕获异常。我们生活在“理想世界”中,但想象一下我们不太幸运的同事——他们很可能会去堵嘴错误信号设施无法处理根本原因(在此处插入更复杂的错误场景)。当您不给客户以错误的方式做事时,编码会变得容易得多。

于 2012-08-10T08:17:52.563 回答
1

在设置器的情况下,开发人员永远不会期望这些方法的返回值,因为他们认为无论如何这将负责设置值。
万一出现异常,这将有助于了解确实有问题并再次查看代码。
而不是runtime exception,您最好定义自己的异常,InvalidBalanceException并指定此方法将在签名本身中抛出此异常。这避免了测试阶段的意外,并决定了开发阶段本身的业务逻辑。

于 2012-08-10T08:12:27.177 回答
0

除了已经给出的答案之外,在名为“setFoo”的函数中返回一个布尔值是非常具有误导性的。如果你翻译一个布尔值,你会得出是/否。因此,在 oop 中返回布尔值的函数应该可以作为一个给出是/否作为答案的问题来阅读,例如 isBalanceSet。

在与同事的讨论中,我们认为普通 setter 的唯一有效返回值是 fluent-interfaces 的类本身。

关于您的问题,如果该类实际验证其属性本身,则抛出异常是更好的解决方案;)

于 2012-08-10T08:29:16.880 回答
0

我个人的看法:这两种方法都有其用途。这取决于为什么会出现这种情况,是否可以防止这种情况发生,客户可以采取哪些措施来防止这种情况发生。

服务器:

method SetBalance(int balance)
{
   // do something only if balance >= 0
}

客户:

myServer.SetBalance(balance);

情况 1: 这种情况的出现只是因为某处(服务器或客户端)的错误。抛出异常。让责任方修复其代码。

情况 2: 从某些外部依赖项接收到错误输入。客户可以很容易地检查前提条件。抛出异常,如果客户对此不满意,请让客户修复其代码。

if(balance>0)
  myServer.SetBalance(balance);
else
  //take appropriate action.

情况 3: 从某些外部依赖项接收到错误输入。客户无法轻松检查前提条件。示例:它需要客户端解析一个字符串,这是服务器的工作。在这里,服务器应该返回成功是有道理的:

bool succeeded = myServer.SetBalance(balance);
if(!succeeded)
  //take appropriate action.

写下我的答案后,我注意到这一切都归结为:客户端不应该使用 try-catch 来调用方法 SetBalance。(要么是错误所以不要捕获异常,或者自己检查前置条件,或者检查返回值)

这是有关相关主题的好读物:http: //blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx

编辑: 乔乔提出了一个很好的观点。如果有可能失败,请重命名方法TrySetBalance() 。

于 2012-08-10T08:48:55.817 回答
0

异常处理是 OOP 中处理错误的首选方法,无论是运行时错误还是逻辑错误。证明异常处理合理性的一个论据是,如果使用错误代码,函数的客户端可能会忘记检查错误代码,从而导致可能不容易发现的潜在错误。然而,如果使用异常处理,即使它没有被捕获,它也会传播直到它被处理。因此,OOP 纯粹主义者总是建议使用异常处理。

于 2012-08-21T12:55:51.593 回答