Tuesday, September 13, 2011

Viewing Contracts

There are many ways to view a contract.  As you edit your class, you naturally see the contract for each method in the header of the method, since it is part of the text.  (In Eiffel, it is part of the syntax of the language; in design-by-contract tools for Java, the contract is typically expressed in the Javadoc comments of classes and methods.)  But what do you do when you want to see the full contract of the method, including inherited parts?  And when you are about to call some method of another class, how do you know what is the full contact for that method?

The contract can have private parts, which are not meaningful to clients.  As I mentioned previously, preconditions must be fully understandable to clients, since otherwise they can't be expected to comply with them.  However, postconditions and invariants may refer to private parts of the implementation.  For example, suppose your Queue class uses a circular buffer, called items, to implement the (bounded) queue.  The implementation invariant should specify that items != null.  This is an important property of the class to its implementer and anyone creating an inheriting class, but it shouldn't be exposed to clients who aren't supposed to know about implementation details.  Similarly, the method that adds an element to the queue may have a postcondition specifying that the write-pointer has advanced by 1 modulo the buffer size.  Again, this is useful information to the implementer, but should be hidden from clients.

The distinction between private and public access levels, in code or in contracts, is usually not clear cut.  For example, Java provides four different access levels; C++ has three, but allows "friends" to access private and protected members; and Eiffel has a selective export mechanism where a class can specify which other classes have access to each of its features.  This means that the same class can present different interfaces to other classes, depending on their access levels.  As always, interfaces include the methods visible to the particular client, as well as the contract.  Different parts of the postconditions and invariants of the contract would be visible to different clients.

The Eiffel development environment can show contracts in different ways, based on whether to show private assertions or not, and whether to show assertions from a single class or show all inherited assertions as well.  However, the views can't be customized by client.  I don't know of any other development environment that can show more than one view of a contract.  Ideally, the environment would be able to show contracts from a supplier's perspective as well as from the perspective of any client.  For example, if I'm editing class A, and place the cursor on a call to a method f of class B, I should be able to see (in a tooltip or in a separate view) the full contract of B.f from the point of view of class A.  Such a view is not difficult to create, although it might require some tedious work.  I consider such a view essential to any development environment that takes design-by-contract seriously.