我应该从构造函数抛出异常吗?


46

我知道我可以在PHP中从构造函数中抛出异常,但我应该这样做吗?例如,如果参数的值不符合我的预期。

还是应该推迟引发异常,直到方法被调用。两种情况下的优缺点是什么?


问题是您是否希望您的用户看到难看的异常错误消息?

15
@LawrenceCherone不,这不是问题。一点也不。问题是当ctor无法从传递给它的参数将对象设置为有效状态时立即引发异常,还是将其推迟到调用该实例上可能具有无效状态的方法之前。不过更适合程序员。

4
@LawrenceCherone你是对的。任何软件都不应该故意失败。它应该继续前进,看看会发生什么。/ s
user253751 '16

@immibis好讽刺是好的。
kodeart

这是一个很棒的问题!!!直到今天,我什至从未考虑过这个想法。
Rhys Johns

Answers:


75

为什么要推迟引发异常?

如果您知道该对象无法使用给定的参数正确实例化,那么您绝对应该引发异常。

否则,有人可能会测试您的对象是否为null(不会),并假设一切都按预期进行。

在不调用对象的情况下,可以对对象执行很多操作:可以将其添加到列表中,可以进行比较,可以将其作为参数发送,等等,等等。所有这些都是对象考虑到它不是有效的对象,这本不应该发生的。


21

如果使用错误的参数调用构造函数,则应该(必须?)引发异常。如果不这样做,那么您可能会得到一个不良物体,该物体将无法正常运行。


17

绝对!!

如果用于构造对象的参数无效或不符合合同规定,则应引发异常。知道对象是由不良数据构成的,那么继续进行流程并不是一个好主意, 如果允许调用者继续进行,则可能导致许多问题。

最好“尽快失败并尽早失败”


7

我知道我可以在PHP中从构造函数中抛出异常,但我应该这样做吗?

这是通知对象构造失败的唯一明智的方法。


2

为什么在实例化对象之前不验证参数集?这样做将确保您的对象将被创建,从而消除了对象故障可能引起的任何副作用。

尽管我知道您可以检查构造函数中的内容并抛出异常,但我更喜欢以不会失败的方式编写构造函数。我在实例化对象之前执行参数验证,然后可以抛出异常而不会使构造函数失败。我通常也不会尝试在构造函数中实例化新对象,而是根据需要选择实例化它们。

只是我的观点。PHP提供了很多自由-尽情享受吧!


我不确定为什么这个答案会被否决。它提供了在对象构造之前使用参数验证的有效方法(“保护”方法),这是为特定(通常是业务)规则设计类/功能的好方法。如果也不能直接回答OP的问题,但这仍然是一个很好的建议:)
kodeart
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.