CSC 205/206/405
Professor Stearns
Introduction to Design by Contract


Papers and other resources

Design by contract means a method trusts its specified interface and doesn't check its preconditions.
Design by contract means the client code trusts the postcondition is met and doesn't check the postcondition.

Run-time (e.g. insufficient memory, non-existent file) errors are outside the contract and must be checked and handled normally.

The design issue is easy to state but often difficult to determine.
Which conditions are trusted and which are checked?

Design By Contract means:

  1. There must be clear, strong pre and postconditions written.

  2. Preconditions are not checked and handled in the normal way.
    (see table below)

  3. Exceptions must be well designed.
    When the interface cannot be trusted (e.g. user input, memory allocation), a consistent exception mechanism must be used. The user must not be left in the dark.
    Question: What should the user see when a precondition is violated in the deployed system?

A simple example is adapted from Writing Solid Code published by Microsoft Press. Design By Contract is a major tenet in this widely adopted book.

Convert to upper case (Non - DBC)
Convert to upper case (DBC)

Notes:
1. This idea can be quite difficult to sell; many developers have a mistaken "bullet-proofing" mentality.
2. Think about code that does check preconditions? How should a precondition violation be handled?


Comparison: DBC and traditional error-checking practice

  at Development time at Run-time Notes
Error-checking The method checks (used) data members and its parameters.
In case of an error, the method triggers an exception or returns an error.
The method code runs as written by the programmer.
Product quality code must handle any "conceivable" error.
In any case, such code must be written for run-time errors (errors caused by the operating environment).
A long discussion on "conceivable" is required for all software projects.
Design by Contract The designer writes strong preconditions against data members and input parameters.
Code to check the preconditions may be:
  1. Omitted entirely; the team believes good programmers and code inspections are sufficient.
  2. Written as asserts (e.g. Java 1.4 Assert)
  3. Included by the compiler (e.g. Eiffel)
  4. Included by a preprocessor tool (e.g. Jass)
But the programmer never, under any circumstance, writes code to check data members and parameters. NEVER!
If there is no run-time error checking code, the method runs with defects in its input; results are indeterminate. The method may work correctly or produce a defect or crash the program or ??

If there is run-time error checking code, that code does something appropriate. It must be possible to disable the run-time code; this may be done at build-time or by the user depending on circumstances.
The code might:
  1. Inform the user. (what should the user be told?)
  2. Gracefully crash the program (Blue screen, flashing light, ???)
  3. Attempt a fix. (ask Dan about his Sara Lee story)
Meyer defines 3 possible outcomes in an Eiffel rescue clause.
  1. Retry
  2. Organized panic
  3. False alarm


Last updated on 1/15/04