1205 S '03
Lectures
 
Lecture 1
Lecture 2
Lecture 3
Lecture 4
Lecture 5
Lecture 6
Lecture 7
Lecture 8
Lecture 9
Lecture 10
Lecture 11
Lecture 12

Interfaces and Contracts


Interfaces as Simple Contracts
----------------------------------------

When you formulate specifications as code, use interfaces---either
formally or informally---to state the basic properties of
functions and methods.

In Java:

A collection of interfaces gives you the terminoloy to talk about
types and operations. For example, in Bazaar we can talk about
- colors using IColor
- equations using IEquation
- cards using ICard
and so on, simply by writing down an empty interface.

As we progress, we can add method signatures to these interfaces
so that we can also discuss what operations we have and how they
make up the program.

For example, in the ITurn interface we know we need three methods:
- rollDie, because a player must be able to roll the die within
a turn
- trade, because a player must be able to trade in pebbles
- buyCard, because a player must be able to buy a card

In terms of code,

interface ITurn {
... rollDie(...);
// roll the die

... trade(...);
// trade in pebbles

... buyCard(...);
// buy a card
}

Next we should specify signatures for these methods, that is, we
should specify in terms of the interfaces (plus pre-defined types)
what these methods consume and what they produce. As we clarify
these things, we should also refine the purpose statements:

interface ITurn {
IColor rollDie(IColor d);
// roll the die; if it's a star, return d

void trade(IColor[] i, IColor[] o);
// trade in i pebbles for o pebbles, i = o must be an equation

int buyCard(ICard c);
// buy card c, obtain score in return
}

Use the parameters of a method signature to state refined purpose
statements.

What do we have now? We have a simple, semi-Java, semi-English
>>contract<< between the person who implements ITurn and the
person who uses ITurn (the implementor of player and possibly
administrator).

A picture:

+--+
| |
consumer | | producer
| |
| |
| |
| |
| |
| |
+--+
interface
contract

The consumer can now program as if there is an implementation:
write consumer-level ("black box") tests; compile classes against
the interface.

The producer could supply a "dumb" implementation of the interface
for basic testing and in parallel produce a better interface.

They can make progress independently and eventually link the
pieces together. That's true even if the consumer and producer are
one and the same person/pair at first.

Method Contracts
----------------------------------------

Let's look at interfaces and what purpose statements can do for
the programmer in this context.

We know from Bazaar that on occasion we need dices with special
behavior. Instead of numbers, a die's sides may display
colors. One of the sides may be special. Not all sides may be
distinct. So let's look at a general interface for a die:

interface IDie {
Object rollDie(Object sides[]);
// Assume that sides is of length 6.
// Randomly pick one of the six objects in sides, uniform distribution
}

We can turn the purpose statement into Boolean conditions that are
true when the method is called and when the method returns. These
conditions are often called "assertions", because we assert that
they must hold at the specified times.

There are two kinds of such conditions:

- preconditions: a condition that must be true *as* the method is
called typically, these conditions involve the
state of the object and the values of the
parameters

- postconditions: a condition that must *after* the method's
computation is completed; typically, these
conditions involve the state of the object and
the *result* of the method.

In our example, the pre- and postconditions completely specify the
behavior of the method. Let's look at an implementation:

last updated on Tue Jan 11 13:12:34 EST 2005generated with PLT Scheme