Contracts as protocols of interaction
Contracts as supported by Eiffel and
Annotated C++ are a very powerful means of
characterizing the interaction between a server object
and a client object.
However, with software becoming increasingly complex,
what we need is a mechanism to characterize
the behavior of collections or compositions of objects
as embodied in the notion of behavioral contracts
as introduced in [HHG90].
A contract (in the extended sense)
lists the objects that participate in the task
and characterizes the dependencies and constraints
imposed on their mutual interaction.
For example, the contract model-view, shown below
(in a slightly different notation than the original
presentation in [HHG90]), introduces
the object model and a collection of view objects.
Also, it characterizes the minimal assumptions with respect
to the functionality these objects must support
and it gives an abstract characterization of
the effect of each of the supported operations.
contract model-view<V> { \c{\fbox{MV(C)}}
subject : model supports [
state : V;
value( val : V ) \$|->\$ [state = val]; notify();
notify() \$|->\$ \$\forall v \e \$views \bl v.update();
attach( v : view ) \$|->\$ v \$\e\$ views;
detach( v : view ) \$|->\$ v \$\not\e\$ views;
]
views : set<view> where view supports [
update() \$|->\$ [view reflects state];
subject( m : model ) \$|->\$ subject = m;
]
invariant:
\$\forall\$ v \$\e\$ views \bl [v reflects subject.state]
instantiation:
\$\forall\$ v \$\e\$ views \bl subject.attach(v) & v.subject(subject);
subject.notify();
}
slide: The Model-View contract
To indicate the type of variables, the notation
is used expressing that variable v
is typed as type.
The object subject of type model has an
instance variable state of type V that
represents (in an abstract fashion) the value
of the model object.
Methods are defined using the notation
Actions may consist either of other method calls
or conditions that are considered to be satisfied
after calling the method.
Quantification as for example in
- v views \bl v.update()
is used to express that the method
is to be called for all elements in views.
The model-view contract specifies
in more formal terms the MV part of the MVC paradigm
discussed in section [MVC].
Recall, that the idea of a model-view pair
is to distinguish between the actual
information (which is contained in the model object)
and the presentation of that information, which is
taken care of by possibly multiple view objects.
The actual protocol of interaction between a model
and its view objects is quite straightforward.
Each view object may be considered as a handler
that must minimally have a method to install
a model and a method update which is invoked,
as the result of the model object calling notify,
whenever the information contained in the model
changes.
The effect of calling is abstractly
characterized as a universal quantification
over the collection of view object.
Calling for subject results in calling
for each view.
The meaning of is abstractly represented as
- update() [view reflects state];
which tells us that the state of the subject
is adequately reflected by the view object.
The invariant clause of the model-view
contract states that every change of the (state of the)
model will be reflected by each view.
The instantiation clause describes, in a rather operational way,
how to initialize each object participating in the contract.
In order to instantiate such a contract, we need to define
appropriate classes realizing the abstract entities
participating in the contract,
and further we need to define how these
classes are related to their abstract counterparts
in the contract by means of what we may call, following [HHG90],
conformance declarations.
Conformance declarations specify, in other words, how
concrete classes embody an abstract role,
similar as in the realization of a partial type
by means of inheritance.