Design by Contract

Design by Contract
Design by Contract
• Design by contract is the process of
developing software based on the
notion of contracts between objects,
which are expressed as assertions.
Design by Contract
• Definitions from The Object Constraint
Language by Jos Warmer, Anneke
Kleppe:
• An invariant for a superclass is
inherited by its subclasses. A subclass
may strengthen the invariant but cannot
weaken it.
Design by Contract
• Definitions from The Object Constraint
Language by Jos Warmer, Anneke Kleppe:
• A precondition may be weakened, not
strengthened, in a redefinition of an operation
in a subclass.
• A postcondition may be strengthened, not
weakened, in a redefinition of an operation in
a subclass.
Design by Contract
• Object oriented software development
builds on familiarity with the real world
by providing a traceable path from realworld objects through their
conceptualisation during analysis and
their construction during design, to their
use during implementation. In the end,
the objects that you implement become
the software system.
Design by Contract
• One way to ensure that a software system
performs its intended functions is based on the
concept of a contract. When an object sends a
message to another object, a form of contract
exists. The receiver is being asked to perform a
service for the sender. The sender is viewed as
a client that requests a service from a supplier
(the receiver or server). Whenever a service is
provided, a contract comes into play: the client
expects the supplier to perform the service
correctly and the supplier expects to be asked
to perform only those services it knows how to
supply.
Design by Contract
• If either of these expectations is not met, the
contract has been broken. Identifying roles in
terms of clients and suppliers (servers) enables
designers to specify the responsibilities of
objects more precisely; this allows clearer
software to be built which, in turn, leads to
greater confidence in the correctness of the
software; the users’ requirements are being
met. The process of developing software based
on contract between objects has come to be
known as Design by Contract.
The contract to produce quality software
• Use cases provide a language for describing
requirements that aim to be understandable to both
technical developers and non-technical customers and
users. A significant part of a use case consists of the
pre-condition and post-condition that constrain it. Preconditions, post-conditions and invariants are
collectively known as assertions. These can be used
to build contracts.
• To the customer (or software purchaser) many
assertions will appear as business rules.
The contract to produce quality
software
• A scenario is a description of a sequence of
actions that illustrate a piece of interesting
behaviour. Just as an object is an instance of a
class, a scenario is said to an instance of a use
case. In the UML, a scenario describes the
interaction and dialogue between the users of a
software system (its actors) and the software
system itself. For a given use case, we expect to
see one main scenario that describes the flow of
events leading to a successful conclusion. There
may be other scenarios that describe alternative or
additions to the main scenario.
The contract to produce quality
software
• Assertions can be introduced early in the
development process, during analysis as contract
on use cases. As development progresses so the
assertions will be refined with more detail being
added and carried through into design and then
into implementation.
The contract to produce quality
software
• Assertions can be included in the final code to be
checked both by the compiler and by the run-time
system. Ultimately, the contract is embodied in the
code and we have a traceable pathway from
analysis to implementation that shows how the
assertions were developed and relates the code
directly to the requirements (DbC).
Contracts in the real world
In the general case: a supplier’s services will
still satisfy a request if their constraints on
inputs (pre-conditions) are a slackening (DbC
calls it weakening) of the requirements on
inputs, and/or their constraints on outputs
(post-conditions) are a tightening (DbC calls it
strengthening) of the requirements on
outputs.
Advantages of DbC
– There are four main advantages to this approach:
– 1 assertions provide accurate documentation for the
implemented classes so that a programmer knows
how to use the classes and what to expect from
them;
– 2 provided they are executable, assertions are an
important aid to testing, but without being an
obstacle to efficiency;
Advantages of DbC
– There are four main advantages to this approach:
– 3 assertions provide a way of controlling inheritance
in which substitutability and redefinition of methods
are allowed;
– 4 provided the programming language has an
exception mechanism that accords with the
principles of DbC, assertions together with the
exception mechanism can be an important aid to
developing mission critical systems.
Contracting, subcontracting and inheritance
– One way of describing what each task, activity or
operation should achieve is to write a form of
contract as follows:
• 1 a description of the task, activity or operation in
question;
• 2 a set of constraints that are assumed to be true before
you can start, which is known as a pre-condition;
• 3 a set of constraints that must be true afterwards, which
is known as a postcondition.
Contracting, subcontracting and inheritance
– The aim is to describe the state changes
required of an operation, activity or task
without having to say how they might be
achieved. Each contract tells you about the
constraints on the expected behaviour of an
operation. In effect, the design can be
deferred while you focus on what must
happen.
Contracting, subcontracting and inheritance
– In the context of software development, a
contract is between two objects: the client
object and the supplier object. The contract
comes into effect when the client uses one of
the services that the supplier object provides.
Since the client object wants the server
object to do something for it, you can view
this relationship as a contract, with conditions
on inputs (pre-conditions) and outputs (postconditions).
Contracting, subcontracting and inheritance
– As an example of how a contract works, consider a
bank account system in which there is a method for
withdrawing an amount of cash from an account. If
there is a limit on the amount by which the account
can be overdrawn, we can specify what the method
should achieve and what should be true before the
method should be invoked, as a contract with the
following pre- and post-conditions:
– pre-condition: there must be sufficient funds in the
account;
– post-condition: the account will have been debited
by the requested amount.
Obligations and benefits on both client and
supplier
– that the pre-condition must be satisfied means the
client must ensure that there are sufficient funds in
the account for the amount to be debited, but the
supplier does not need to check that there are
sufficient funds (if the pre-condition is not satisfied,
the client cannot expect to get the service it would
like);
– that the post-condition must be satisfied means the
supplier must debit the amount from the account,
and the client receives this information.
Discovering Contracts
– When defining contracts, new classes,
attributes or associations will be discovered,
so existing classes may have to amended
Ask two questions:
– pre-condition: What is needed for this
operation to be allowed to start?
– post-condition: What will have happened as a
result of this operation?
Subcontracting and inheritance
The generalization relationship requires the
use of the substitutability test to determine
whether one object was a generalization of
another: if an object of one type can be
substituted for an object of another type in all
circumstances, the type of the first object is a
subtype of the second; that is, the second
object is a generalization of the first.
Subcontracting and inheritance
When we come to examine the idea of
subcontracts in software we must bear in
mind that objects and classes relate to one
another in two basic ways:
1 through associations (e.g. has-a instance
level);
2 through generalizations (the is-a
relationship at class level).
In general instances are related to classes i.e.
an object is an instance of a class.
Subcontracting and inheritance
If the objects of the subclasses are to be
substitutable for those of the parent class, a
certain relationship must hold. This
relationship can be expressed in terms of the
pre- and post-conditions associated with the
overridden methods in the two classes.
Constraints on behaviour
– We can constrain the behaviour of the
system in terms of:
• objects that are created and/or destroyed;
• links between objects that are created and/or
destroyed;
• attributes whose values are changed.
Constraints in general
• Pre-condition: Describes something that must be
true when client sends message.
• Post-condition: Describes something that must be
true when the server completes operation.
• Class invariants: must always be true
e.g.#onPlane<=MaxAllowed must be true.
• Type constraints: limiting operations
• Multiplicity constraints e.g. 1:M.
• Object Constraint Language OCL handles constraints
in general.
Design by contract
• What does inheritance mean in relation to DbC?
Overridden methods must conceptually do the
same job.
• Demand no more: promise no less.
• Demand no more: a subclass must accept any
message and arguments that the superclass
accepts. Therefore a subclass preconditions must
be no stronger than that of the superclass.
Design by contract
• Demand no more: Promise no less.
• Promise no less: any assumptions which were
valid when the superclass’s implementation was
used should still be valid for the subclass
implementation. Therefore the subclass’s postconditions must be at least as strong as the
superclasses post-conditions.
FROM REQUIREMENTS TO
CODE
• In an OO system, pre- and post-conditions can be
related to a client–supplier contract between objects
and how they can be usefully employed in the process
known as DbC. Part of the value of DbC was that it
allowed traceability from requirements through to
code.
• We need an initial encoding of requirements as
assertions. These must be transformed into assertions
about code. DbC can improve the documentation of
classes, but linking these requirement and code
assertions.
DbC helps to move from
requirements to code
• To move to code we need to:
• describe the relationship between invariants, and pre- and
post-conditions, in English;
• use assertions to express contracts between the
components of a simple system;
• write assertions in the OCL language;
• incorporate these assertions into a Java interface in a
way that captures the specification of its behaviour and
supports the notion of DbC;
• implement both the supplier and client code in
accordance with a simple contract;
• Note the difference between a conditional statement
which controls the flow of a program and an assertion.
Monitoring assertions
• At high level errors and defects can be defined
as:
– errors = problems found before release
– defects = problems found after release
• However in the programming activity the term
defect can be defined as an implementation that
does not comply with a specification.
The role of assertions
• Assertions are ways of describing the conditions
under which software elements will and will not
work (pre-conditions) and the conditions that
they will achieve (post-conditions). If the supplier
and its clients are correct, that is, keep to their
contract, assertions should always evaluate to
true. In other words, an assertion violation, which
would be detected at run-time, is an indication of
a defect in the software.
The role of assertions
• To Repeat: An assertion violation, which would
be detected at run-time, is an indication of a
defect in the software with respect to it’s
specification.
• A pre-condition violation indicates a defect in the
client.
• A post-condition violation is a defect in the
supplier.
The role of assertions
• The use of precisely defined contracts clearly assigns all
responsibilities to either the client or the supplier. The
stronger the pre-condition, that is, the more restrictive it
is, the higher the burden on the client (there are more
conditions to be satisfied before the client is allowed to
invoke the supplier) but the easier it makes the task of
the supplier. In practice, it has been found that designs
that concentrate on doing a well-defined job are more
successful than those that try to handle too many cases.
In terms of pre-conditions, this implies that stronger preconditions are better than weak ones. Note that this
strengthening needs to be balanced with the benefits that
accrue from the weakening of pre-conditions e.g. easier
to use?
FROM REQUIREMENTS TO CODE: The
subtyping contract
• Demand no more: promise no less.
• What does this mean for behaviour of a
subclass? Overridden methods must
conceptually do the same job as the method in
the superclass.
• Demand no more: a subclass must accept any
message and arguments that the superclass
accepts. Therefore a subclass preconditions
must be no stronger than that of the
superclass. (Roughly speaking: we should not
“turn off” inheritance)
FROM REQUIREMENTS TO CODE: The
subtyping contract
• Demand no more: Promise no less.
• Promise no less: any assumptions which were
valid when the superclass’s implementation was
used should still be valid for the subclass
implementation. Therefore the subclass’s postconditions must be at least as strong as the
superclasses post-conditions. (Roughly speaking:
inheritance is strict extension not a reduction)
•
DbC can be used to ensure that the behaviour
of inherited operations ‘make sense’.
• The is-a relationship is a way of determining when
the concepts behind the classes are related through
inheritance. For a subclass to be a subtype, each
instance of it must respond to the ‘same operations’
as instantiations of the superclass.
• What is the important feature of DbC,
which shows that it can be used to improve
quality?
• Solution
• DbC allows the development of a software
system to be traced from requirements
through to code.
Client/Server
• In a system using Design By Contract what is
the relevance of invariant, pre-conditions and
post-conditions to:
• The client object which uses an operation?
• The server object which provides an operation?
Clients/suppliers
• Clients are responsible for ensuring
preconditions are met, they can assume the
post-conditions hold after the operation has
been performed providing the preconditions are
met.
• Supplier can assume that the pre-condition
hold if they trust the client. It is also
responsible for ensuring post-condition hold if
the pre-condition are met. It must ensure that
the invariant holds when an object is created
and after every method call on that object.
Main advantages of using
design by contract
• 1) traceability of assertions from analysis to
implementation allows the developer to associate
runtime activities or errors with design artefacts,
hence a runtime error may be traceable to a design
decision or design refinement. (a use case).
• 2) a (semi) formal way of stating correctness, the
implementation respects the invariants, pre/post
conditions in the specification. This can be agreed
upon by both developer and client to be correct with
respect to the specification.
Additional advantages of using
design by contract
• Using design by contract means that assertions can be
introduced early in the development process, during analysis.
• As development progresses so the assertions will be refined
with more detail being added. Assertions can be carried
through into design and then into implementation.
• Importantly, assertions can be included in the final code to be
checked both by the compiler and by the run-time system.
• Ultimately, the contract is embodied in the code and we have a
traceable pathway from analysis to implementation that shows
how the assertions were developed and relates the code directly
to the requirements.
• At the implementation level, if the software representing the
client and supplier meets its contract we can say that the
software is correct with respect to its specification.
DbC and class hierarchies
• A subclass is supposed to be able to fulfil the contract entered into by the
superclass.
• An object of a class subclass should be substitutable for an object of the
superclass.
• An object of a subclass is supposed to be usable everywhere that the
superclass is.
• If the subclass is supposed to be able to fulfil the contract entered into by the
superclassthen the overridden methods must conceptually do the same job.
• Assertions implemented in hierarchies should obey the following rule:
• Demand no more: promise no less.
• Demand no more: a subclass must accept any message and arguments that
the superclass accepts. Therefore a subclass preconditions must be no
stronger than that of the superclass.
• Promise no less any assumptions which were valid when the superclass’s
implementation was used should still be valid for the subclass
implementation. Therefore the subclass’s post-conditions must be at least as
strong as the superclasses post-conditions.
DbC and class hierarchies
• Contracts are inherited, just like
methods. When a method is
overridden in a subclass, that class
may specify its own contracts that
modify those of the superclass
method. A subclass method must:
• Accept all input valid to the
superclass method.
• Meet all guarantees of the superclass
method.
DbC and class hierarchies
• The overridden method may "weaken the precondition
and strengthen the postcondition".
• The preconditions for the subclass method are logical
or-ed with the super class preconditions.
• The postconditions are logical and-ed.
• This requires that the subclass accept all input valid to
the super class method, and may accept more that is
invalid to the super class. However, it must abide by
the guarantees made by its parent, though it is given
the option of strengthening those guarantees