【发布时间】:2010-09-25 12:13:13
【问题描述】:
我很想听听您在操作期间使用什么技术来验证对象的内部状态,从它自己的角度来看,这些技术只会因内部状态不佳或不变的破坏而失败。
我的主要关注点是 C++,因为在 C# 中,官方和流行的方式是抛出异常,而在 C++ 中,并没有一种single 方法可以做到这一点(好吧,不是真的在 C#或者,我知道)。
请注意,我不是在谈论函数参数验证,而更像是类不变完整性检查。
例如,假设我们想要一个 Printer 对象到 Queue 异步打印作业。对于Printer的用户来说,该操作只能成功,因为异步队列结果在另一个时间到达。因此,没有相关的错误代码可以传达给调用者。
但是对于Printer对象,如果内部状态不好,即类不变量被破坏,则此操作可能会失败,这基本上意味着:一个错误。 Printer 对象的用户不一定会对这种情况感兴趣。
就我个人而言,我倾向于混合使用三种内部状态验证方式,但我无法真正决定哪一种是最好的,如果有的话,只能确定哪一种绝对是最差的。我想听听你对这些的看法,也想听听你在这件事上分享你自己的经验和想法。
我使用的第一个样式 - 以可控的方式失败比损坏数据更好:
void Printer::Queue(const PrintJob& job)
{
// Validate the state in both release and debug builds.
// Never proceed with the queuing in a bad state.
if(!IsValidState())
{
throw InvalidOperationException();
}
// Continue with queuing, parameter checking, etc.
// Internal state is guaranteed to be good.
}
我使用的第二种样式 - 崩溃不可控比损坏数据更好:
void Printer::Queue(const PrintJob& job)
{
// Validate the state in debug builds only.
// Break into the debugger in debug builds.
// Always proceed with the queuing, also in a bad state.
DebugAssert(IsValidState());
// Continue with queuing, parameter checking, etc.
// Generally, behavior is now undefined, because of bad internal state.
// But, specifically, this often means an access violation when
// a NULL pointer is dereferenced, or something similar, and that crash will
// generate a dump file that can be used to find the error cause during
// testing before shipping the product.
}
我使用的第三种方式 - 比损坏的数据更好地进行静默和防御性的纾困:
void Printer::Queue(const PrintJob& job)
{
// Validate the state in both release and debug builds.
// Break into the debugger in debug builds.
// Never proceed with the queuing in a bad state.
// This object will likely never again succeed in queuing anything.
if(!IsValidState())
{
DebugBreak();
return;
}
// Continue with defenestration.
// Internal state is guaranteed to be good.
}
我对风格的看法:
- 我认为我更喜欢第二种样式,它不会隐藏故障,前提是访问冲突实际上会导致崩溃。
- 如果它不是不变量中涉及的 NULL 指针,那么我倾向于倾向于第一种样式。
- 我真的不喜欢第三种风格,因为它会隐藏很多错误,但我知道有人更喜欢在生产代码中使用它,因为它会产生一种不会崩溃的强大软件的错觉(功能只会停止运行,如在损坏的
Printer对象上的排队中)。
您更喜欢其中任何一种还是您有其他方法可以实现这一点?
【问题讨论】:
标签: c# c++ validation invariants