Software Engineering Design by Contract 1 Design by Contract ™
-
date post
22-Dec-2015 -
Category
Documents
-
view
224 -
download
2
Transcript of Software Engineering Design by Contract 1 Design by Contract ™
Design by Contract2 Software Engineering
Design by Contract
Every software element is intended to satisfy a certain goal, for the benefit of other software elements (and ultimately of human users).
This goal is the element’s contract.
The contract of any software element should be Explicit. Part of the software element itself.
Design by Contract3 Software Engineering
Design by Contract: applications
Built-in correctness Automatic documentation Self-debugging, self-testing
code Get inheritance right Get exceptions right Give managers better control tools
Design by Contract4 Software Engineering
Constructing systems as structured collections of cooperating software elements — suppliers and clients — cooperating on the basis of clear definitions of obligations and benefits
These definitions are the contracts
Software construction:the underlying view
Design by Contract5 Software Engineering
Properties of contracts
A contract: Binds two parties (or more): supplier, client Is explicit (written) Specifies mutual obligations and benefits Usually maps obligation for one of the parties
into benefit for the other, and conversely Has no hidden clauses: obligations are those
specified Often relies, implicitly or explicitly, on general
rules applicable to all contracts (laws, regulations, standard practices)
Design by Contract6 Software Engineering
A human contract
Client
Supplier
(Satisfy precondition:)
Bring package before 4 p.m.; pay fee.
(Satisfy postcondition:)
Deliver package by 10 a.m. next day.
OBLIGATIONS
(From postcondition:)
Get package delivered by 10 a.m. next day.
(From precondition:)
Not required to do anything if package delivered after 4 p.m., or fee not paid.
BENEFITSdeliver
Design by Contract7 Software Engineering
EiffelStudio documentation
Produced automatically from class textAvailable in text, HTML, Postscript, RTF, FrameMaker and many other formatsNumerous views, textual and graphical
Design by Contract8 Software Engineering
Contracts for documentation
LINKED_LIST Documentation,generated by EiffelStudio
Demo
Design by Contract9 Software Engineering
Contract form: Definition
Simplified form of class text, retaining interface elements only:
Remove any non-exported (private) feature.
For the exported (public) features: Remove body (do clause). Keep header comment if present. Keep contracts: preconditions, postconditions,
class invariant. Remove any contract clause that refers to a
secret feature. (What’s the problem?)
Design by Contract10 Software Engineering
The different forms of a class
Elements fromthe class only
Elements from the class and it’s ancestors
Text view:text form
All features and contract clauses
Only the exported (non secret) elements
Contract view:short form
Flat view:flat form
Interface view:flat short form
Design by Contract11 Software Engineering
Export rule for preconditions
In
some_property must be exported (at least) to A, B and C!No such requirement for postconditions and invariants.
feature {A, B, C}
r (…) is
require
some_property
Chair of Software Engineering
deferred class VAT inherit
TANK
feature
in_valve, out_valve: VALVE
fill is-- Fill the vat.
require in_valve.open out_valve.closed
deferred ensure
in_valve.closed out_valve.closed is_full
end
empty, is_full, is_empty, gauge, maximum, ... [Other features] ...
invariant
is_full = (gauge >= 0.97 maximum) and (gauge <= 1.03 maximum)
end
Contracts for analysis, specification
Design by Contract13 Software Engineering
Contracts for testing and debugging
Contracts express implicit assumptions behind code
A bug is a discrepancy between intent and code Contracts state the intent!
In EiffelStudio: select compilation option for run-time contract monitoring at level of:
Class Cluster System
May disable monitoring when releasing softwareA revolutionary form of quality assurance
Design by Contract14 Software Engineering
Lists in EiffelBase
“Iowa"
Cursor
item
index
count1
forthback
finishstart
afterbefore
Design by Contract15 Software Engineering
Trying to insert too far right
Cursor(Already past last element!)
count1
after
"Iowa"
Design by Contract17 Software Engineering
Moving the cursor forward
"Iowa"
Cursor
index
count1
forth
afterbefore
Design by Contract19 Software Engineering
Where the cursor may go
count+1
Valid cursor positions
item
count1
afterbefore
0
Design by Contract21 Software Engineering
Contract monitoring
A contract violation always signals a bug:
Precondition violation: bug in client
Postcondition violation: bug in routine
Design by Contract22 Software Engineering
Contracts and inheritance
Issues: what happens, under inheritance, to
Class invariants?
Routine preconditions and postconditions?
Design by Contract23 Software Engineering
Invariants
Invariant Inheritance rule: The invariant of a class automatically includes
the invariant clauses from all its parents, “and”-ed.
Accumulated result visible in flat and interface forms.
Design by Contract24 Software Engineering
Contracts and inheritance
r isrequire
ensure
r isrequire
ensure
a1: A
a1.r (…)…
Correct call in C: if a1. then a1.r (...) -- Here a1. hold end
r ++
C A
D B
ClientInheritance
++ Redefinition
Design by Contract25 Software Engineering
Assertion redeclaration rule
When redeclaring a routine, we may only:
Keep or weaken the precondition
Keep or strengthen the postcondition
Design by Contract26 Software Engineering
A simple language rule does the trick!
Redefined version may have nothing (assertions kept by default), or
require else new_preensure then new_post
Resulting assertions are: original_precondition or new_pre
original_postcondition and new_post
Assertion redeclaration rule in Eiffel
Design by Contract27 Software Engineering
Contracts as a management tool
High-level view of modules for the manager:
Follow what’s going on without reading the code
Enforce strict rules of cooperation between units of the system
Control outsourcing
Design by Contract28 Software Engineering
Checking input: filter modules
Contracts are not input checking tests...
... but they can help weed out undesirable input
External objects
Input &validation modules
Processing modules
Preconditionshere onlyNo preconditions!
Postconditions
Design by Contract29 Software Engineering
Precondition design
The client must guarantee the precondition before the call.
This does not necessarily mean testing for the precondition.
Scheme 1 (testing):
if not my_stack.is_full thenmy_stack.put (some_element)
end
Scheme 2 (guaranteeing without testing):
my_stack.remove...my_stack.put (some_element)
Design by Contract30 Software Engineering
Another example
sqrt (x, epsilon: REAL): REAL is-- Square root of x, precision epsilon
require
x >= 0
epsilon >= 0
do...
ensure
abs (Result ^ 2 – x) <= 2 * epsilon * Result
end
Design by Contract31 Software Engineering
The contract
Client
Supplier
(Satisfy precondition:)
Provide non-negative value and precision that is not too small.
(Satisfy postcondition:)
Produce square root within requested precision.
OBLIGATIONS
(From postcondition:)
Get square root within requested precision.
(From precondition:)
Simpler processing thanks to assumptions on value and precision.
BENEFITSsqrt
Design by Contract32 Software Engineering
Not defensive programming
It is not acceptable to have a routine of the form
sqrt (x, epsilon: REAL): REAL is-- Square root of x, precision epsilon
requirex >= 0
epsilon >= 0do
if x < 0 then… Do something about it (?) …
else… normal square root computation
… endensure
abs (Result ^ 2 – x) <= 2 * epsilon * Result end
Design by Contract33 Software Engineering
Not defensive programming
For every consistency condition that is required to perform a certain operation:
Assign responsibility for the condition to one of the contract’s two parties (supplier, client).
Stick to this decision: do not duplicate responsibility.
Simplifies software and improves global reliability.
Design by Contract34 Software Engineering
Interpreters
class BYTECODE_PROGRAM feature
verified: BOOLEAN
trustful_execute (program: BYTECODE) isrequire
ok: verifieddo
...end
distrustful_execute (program: BYTECODE) isdo
verifyif verified then
trustful_execute (program)end
end
verify isdo
...end
end
Design by Contract35 Software Engineering
How strong should a precondition be?
Two opposite styles:
Tolerant: weak preconditions (including the weakest, True: no precondition).
Demanding: strong preconditions, requiring the client to make sure all logically necessary conditions are satisfied before each call.
Partly a matter of taste.
But: demanding style leads to a better distribution of roles, provided the precondition is:
Justifiable in terms of the specification only. Documented (through the short form). Reasonable!
Design by Contract36 Software Engineering
A demanding style
sqrt (x, epsilon: REAL): REAL is-- Square root of x, precision epsilon-- Same version as before
require
x >= 0epsilon >= 0
do...
ensure
abs (Result ^ 2 – x) <= 2 * epsilon * Result
end
Design by Contract37 Software Engineering
sqrt (x, epsilon: REAL): REAL is-- Square root of x, precision epsilon
requireTrue
doif x < 0 then
… Do something about it (?) …else
… normal square root computation … computed := True
endensure
computed implies abs (Result ^ 2 – x) <= 2 * epsilon *
Result end
A tolerant style
NO INPUT TOO BIG OR TOO SMALL!
Design by Contract38 Software Engineering
Contrasting styles
put (x: G) is-- Push x on top of stack.
requirenot is_full
do....
end
tolerant_put (x: G) is-- Push x if possible, otherwise set impossible to-- True.
doif not is_full then
put (x)else
impossible := Trueend
end
Design by Contract39 Software Engineering
Invariants and business rules
Invariants are absolute consistency conditions.
They can serve to represent business rules if knowledge is to be built into the software.
Form 1
invariant
not_under_minimum: balance >=
Minimum_balance
Form 2
invariantnot_under_minimum_if_normal:normal_state implies
(balance >= Minimum_balance)
Design by Contract40 Software Engineering
Power of the assertion language
Assertion language:
Not first-order predicate calculus
But powerful through:Function calls
Even allows to express:Loop properties
Design by Contract41 Software Engineering
Loop trouble
Loops can be hard to get right:
“Off-by-one” Infinite loops Improper handling of borderline cases
For example: binary search feature
Design by Contract42 Software Engineering
The answer: loop contracts
Use of loop variants and invariants.
A loop is a way to compute a certain result by successive approximations.
(e.g. computing the maximum value of an array of integers)
Design by Contract43 Software Engineering
Computing the max of an array
highest (sl: LIST [STRING]): STRING is-- Greatest element of sl
requiresl /= Void
not sl.is_emptydo
fromsl.start ; Result := ""
untilsl.after
loop Result := greater (Result, sl.item)
sl.forthend
end
Design by Contract44 Software Engineering
Loop as approximation strategy
s1 s2 si sn
Result = s1
Result = Max (s1, s2)
Result = Max (s1, s2, ..., si)
Result = Max (s1, s2, ..., si , ..., sn)
Design by Contract45 Software Engineering
The loop invariant
fromsl.start ; Result := "“
invariantsl.index >= 1sl.index <= sl.count + 1-- Result is greatest of elements so far
untilsl.after
loop Result := greater (Result, sl.item)
sl.forthend
Design by Contract46 Software Engineering
Loop invariant
(Do not confuse with class invariant)
Property that is:
Satisfied after initialization (from clause)
Preserved by every loop iteration (loop clause) when executed with the exit condition (until clause) not satisfied
Design by Contract47 Software Engineering
The loop invariant
fromsl.start ; Result := ""
invariantsl.index >= 1sl.index <= sl.count + 1-- Result is greatest of elements so far
untilsl.after
loop Result := greater (Result, sl.item)
sl.forthend
Design by Contract48 Software Engineering
The loop invariant (better)
fromsl.start ; Result := ""
invariantsl.index >= 1sl.index <= sl.count + 1-- If there are any previous elements, Result is the
greatestuntil
sl.afterloop
Result := greater (Result, sl.item)
sl.forthend
Design by Contract49 Software Engineering
The effect of the loop
from sl.start ; Result := ""invariant sl.index >= 1 sl.index <= sl.count + 1 -- Result is greatest of elements so faruntil sl.afterloop Result := greater (Result, sl.item)
sl.forthend
Invariant satisfied after initialization
Invariant satisfied after each iteration
Exit condition satisfied at end
At end: invariant and exit condition
• All elements visited (sl.after )
• Result is highest of their names
Design by Contract50 Software Engineering
Loop semantics rule
The effect of a loop is the combination of:
Its invariant
Its exit condition
Design by Contract51 Software Engineering
How do we know the loop terminates?
fromsl.start ; Result := "“
invariant sl.index >= 1 sl.index <= sl.count + 1-- If there are any previous elements, Result is the
greatestuntil
sl.afterloop
Result := greater (Result, sl.item)
sl.forthend
Design by Contract52 Software Engineering
Loop variant
Integer expression that must:
Be non-negative when after initialization (from)
Decrease (i.e. by at least one), while remaining non-negative, for every iteration of the body (loop) executed with exit condition not satisfied
Design by Contract53 Software Engineering
The variant for our loop
fromsl.start ; Result := "“
variantsl.count − sl.index + 1
invariant sl.index >= 1 sl.index <= sl.count + 1-- If there are any previous elements, Result is the
greatestuntil
sl.afterloop
Result := greater (Result, sl.item)
sl.forthend
Design by Contract54 Software Engineering
Another contract construct
Check instruction: ensure that a property is True at a certain point of the routine execution.
E.g. Tolerant style example: Adding a check clause for readability.