Could Designing by Contract (DbC) be a way to program defensively?
Is one way of programming better in some cases than the other?
Design by Contract and defensive programming are in some sense opposites of each other: in DbC, you define contracts between collaborators and you program under the assumption that the collaborators honor their contracts. In defensive programming, you program under the assumption that your collaborators violate their contracts.
A real square root routine written in DbC style would state in its contract that you aren’t allowed to pass in a negative number and then simply assume that it can never encounter a negative number. A real square root routine written defensively would assume that it is passed a negative number and take appropriate precautions.
Note: it is of course possible that in DbC someone else will check the contract. In Eiffel, for example, the contract system would check for a negative number at runtime and throw an appropriate exception. In Spec#, the theorem prover would check for negative numbers at compile time and fail the build, if it can’t prove that the routine will never get passed a negative number. The difference is that the programmer doesn’t make this check.
Could Designing by Contract (DbC) be a way to program defensively?
Yes.
“Defensive Programming” is often an excuse to waste time. It often wastes time checking for things that will cause ordinary exceptions. Instead of the exceptions, extra IF statements are written instead of exception-handling clauses.
Define the contract and be done with it.
When someone violates the contract, the program will — in the normal course of events — break and raise normal exceptions which can be normally handled.
“Defensive programming” and “Error prevention” can be shown to add errors (because the error prevention checks are themselves erroneous) rather than prevent errors.
Exception handling can silence, log and handle an exception far better than “Defensive Programming”.
7