Answers:
在某种意义上,按合同进行设计和防御性编程是相反的:在DbC中,您定义协作者之间的合同,并在假定协作者遵守合同的前提下进行编程。在防御性编程中,您是在假定协作者违反合同的前提下进行编程的。
用DbC样式编写的实平方根例程将在其合同中声明不允许您传递负数,然后简单地假定它永远不会遇到负数。防御性写的实平方根例程将假定它已传递负数并采取适当的预防措施。
注意:在DbC中,当然有可能其他人会检查合同。例如,在Eiffel中,合同系统将在运行时检查负数并抛出适当的异常。在Spec#中,如果无法证明例程永远不会传递负数,则定理证明者将在编译时检查负数,并使构建失败。区别在于程序员不进行此检查。
合同设计(DbC)是否可以成为防御性编程的一种方式?
是。
“防御性编程”通常是浪费时间的借口。经常浪费时间检查会引起普通异常的事情。除了异常以外,还编写了额外的IF语句,而不是异常处理子句。
定义合同并完成合同。
当某人违反合同时,在正常情况下,该程序将中断并引发可以正常处理的异常。
可以显示“防御性编程”和“错误预防”添加错误(因为错误预防检查本身就是错误的)而不是防止错误。
异常处理可以使异常静默,记录和处理异常,这比“防御性编程”要好得多。