Understanding design by contract is, I think, important for software quality in OOP because the principles are clear and efficient.
B. Meyer introduced the idea in 1988. It takes advantage of assertions as defined by C.A.R. Hoare (1969), the seminal work of an eponymous logic.
Assertions are associated to an object method and qualified in one of three categories :
- Preconditions are assertions true before executing the method
- Postconditions are assertions true after executing the method
- Invariants are assertions true before and after executing the method
In practice...
Meyer includes his idea in the Eiffel programming language : the assertions are checked in a static way (at compile time).
If the Java programming language provides support for assertions, these are checked only in a dynamic way (at runtime) and disabled by default. Because of runtime checking, exceptions are largely used instead of assertions. In Java, a proper use of exceptions can be more meaningful to the programmer than a proper use of assertions because it provides more details about the malfunction conditions (the stack trace). At first glance, assertions (in the design by contract way) seem to be very far from exceptions. This is to some extent a paradox: I think the developer should consider assertions concepts every time he uses exceptions.
In Effective Java , Bloch defines checked exceptions as recoverable conditions and runtime exceptions as programming errors.
In an non-Java context, Fowler says an exception is a situation where preconditions are satisfied but postconditions can not be satisfied.
I think that, to respect Bloch terms,
- Runtime exceptions should be used for checking preconditions
- Checked exceptions should be used when preconditions are true but postconditions can not be satisfied, assuming that the method is correct (e.g. the network connection is broken).
If a runtime exception is raised, the calling method should be bugged (or its preconditions are not properly checked).
Some extensions to the Java platform provide support for static testing (assertions checking at compile time). For example, JML takes advantage of Java comments: this is interesting for traditional compiling compliance.