Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

iContract: Design by Contract in Java

iContract allows you to explicitly specify your class contracts; no more guesswork as to what your classes promise

  • Print
  • Feedback
Wouldn't it be nice if all Java classes that you use, including your own, lived up to their promises? In fact, wouldn't it be nice if you actually knew exactly what a given class promises? If you agree, read on -- Design by Contract and iContract come to the rescue.

Note: The code source for the examples in this article can be downloaded from Resources.

Design by Contract

The Design by Contract (DBC) software development technique ensures high-quality software by guaranteeing that every component of a system lives up to its expectations. As a developer using DBC, you specify component contracts as part of the component's interface. The contract specifies what that component expects of clients and what clients can expect of it.

Bertrand Meyer developed DBC as part of his Eiffel programming language. Regardless of its origin, DBC is a valuable design technique for all programming languages, including Java.

Central to DBC is the notion of an assertion -- a Boolean expression about the state of a software system. At runtime we evaluate the assertions at specific checkpoints during the system's execution. In a valid software system, all assertions evaluate to true. In other words, if any assertion evaluates to false, we consider the software system invalid or broken.

DBC's central notion somewhat relates to the #assert macro in C and C++ programming language. However DBC takes assertions a zillion levels further.

In DBC, we identify three different kinds of expressions:

  • Preconditions
  • Postconditions
  • Invariants


Let's examine each in more detail.

Preconditions

Preconditions specify conditions that must hold before a method can execute. As such, they are evaluated just before a method executes. Preconditions involve the system state and the arguments passed into the method.

Preconditions specify obligations that a client of a software component must meet before it may invoke a particular method of the component. If a precondition fails, a bug is in a software component's client.

Postconditions

In contrast, postconditions specify conditions that must hold after a method completes. Consequently, postconditions are executed after a method completes. Postconditions involve the old system state, the new system state, the method arguments, and the method's return value.

Postconditions specify guarantees that a software component makes to its clients. If a postcondition is violated, the software component has a bug.

Invariants

An invariant specifies a condition that must hold anytime a client could invoke an object's method. Invariants are defined as part of a class definition. In practice, invariants are evaluated anytime before and after a method on any class instance executes. A violation of an invariant may indicate a bug in either the client or the software component.

Assertions, inheritance, and interfaces

All assertions specified for a class and its methods apply to all subclasses as well. You can also specify assertions for interfaces. As such, all assertions of an interface must hold for all classes that implement the interface.

  • Print
  • Feedback

Resources