Eiffel in Depth Bertrand Meyer Emmanuel Stapf (Eiffel Software) Pei Yu
Eiffel in Depth Bertrand Meyer With material by Emmanuel Stapf (Eiffel Software) & members of the...
-
Upload
breana-artis -
Category
Documents
-
view
218 -
download
0
Transcript of Eiffel in Depth Bertrand Meyer With material by Emmanuel Stapf (Eiffel Software) & members of the...
Eiffel in Depth
Bertrand Meyer
With material by Emmanuel Stapf (Eiffel Software)
& members of the ETH Chair of Software Engineering
Chair ofSoftware Engineering
2
Plan of these slides
1 Overview 2 The
environment(s) 3 Method overview 4 Language basics 5 Dynamic model 6 Genericity &
inheritance 7 Design by
Contract™
8 External interface 9 Agents 10 Advanced design 11 Advanced
mechanisms 12 Conclusion 13 Supplements
3
Purpose of this course
To give you an in-depth understanding of a software method, language and environment: Eiffel (and EiffelStudio)
To improve your understanding of software engineering and software architecture
To give you a feel for the challenges involved in both software design and language design
4
The software of the future
Product quality Correctness Robustness Security
Process quality Fast development No semantic gap (“impedance mismatch”) between developers and other stakeholders Self-validating, self-testing Ease of change Reusability
5
- 1 -
Overview
6
Why Eiffel?
Productivity: faster time to market, fewer developers
Reliability: fewer bugs
Extendibility: be responsive to customer needs
Reuse: stand on the shoulder of giants
Efficiency: make the best use of hardware resources
Maintainability: spend your time on new developments
7
Language versions
Eiffel 1, 1986Classes, contracts, genericity, single and
multipleinheritance, garbage collection, …
Eiffel 2, 1988 (Object-Oriented Software Construction)Exceptions, constrained genericity
Eiffel 3, 1990-1992 (Eiffel: The Language)Basic types as classes, infix & prefix operators…
Eiffel 4, 1997“Precursor” and agents
Eiffel 5, ECMA Standard, 2005, revised 2006, and ISO standard, November 2006www.ecma-international.org/publications/standards/Ecma-367.htm
Attached types, conversion, assigner commands…
8
Eiffel: Method, Language, Environment
Method : Applicable throughout the lifecycle Object-oriented to the core Seamless development Based on Design by Contract™ principles
Language : Full power of object technology Simple yet powerful, numerous original features ISO standard (2006)
Environment : Integrated, provides single solution, including
analysis and modeling Lots of platforms (Unix, Windows, VMS, .NET…) Open and interoperable
99
Some typical users
Axa RosenbergInvestment management: from $2 billion to >$100 billion 2 million linesChicago Board of Trade Price reporting system Eiffel + CORBA + Solaris + Windows + …Xontech (for Boeing) Large-scale simulations of missile defenseNorthrop-Grumman
Swedish social security: accident reporting & management
(Eiffel) Price Reporting System
The Chicago Board of Trade
See: eiffel.co
m
1010
Learning Eiffel
Simple syntax, no cryptic symbols
Eiffel programmers know all of Eiffel Wide variety of user backgrounds
“If you can write a conditional,you can write a contract”
Fast learning curve Lots of good models to learn from Strong style rules
May need to “unlearn” needless tricks
11
The Eiffel method: some principles
Abstraction Information hiding Seamlessness Reversibility Design by Contract Open-Closed principle Single choice principle Single model principle Uniform access principle Command-query separation principle Option-operand separation principle Style matters ... See
next...
12
The Eiffel language
Classes
Uniform type system, covering basic types
Genericity
Inheritance, single and multiple
Conversion
Covariance
Statically typed
Built-in Design by Contract mechanisms
Agents: objects encapsulating behavior
“Once” mechanisms, replacing statics and globals
Void safety (new!)
13
Libraries
Fundamental data structures and algorithms
Portable graphics
Internet, Web
Lexical analysis, parsing
Database interfaces
14
Dogmatism and flexibility
Dogmatic where it counts:
Information hiding (e.g. no x.a := b) Overloading “One good way to do anything” Style rules
Flexible when it makes no point to harass programmers:
Give standard notations (e.g. a + b) an O-O interpretation
Syntax, e.g. semicolon
15
The Eiffel language: there is a hidden agenda
That you forget it even exists
16
- 2 -
The environment
17
EiffelStudio
Serialization
EiffelStore
EiffelStudio
Ansi C
Executable system
IL
EiffelBase
WEL
EiffelVision
EiffelNet
EiffelWeb
EiffelMath
EiffelCOM
Persistent objects
Eiffel Runtime
Databases (Rel,
OO)
C compilation
JitterEiffel compilation
User classes
General library
Win32 library
Networking
Web development
Advanced numerics
External C/C++/Java
.NET Assemblies
EiffelBuild
GUI builder
Multiplatform GUI library
Browsing, fast compiling (Melting Ice™), debugging, diagrams, metrics...
18
EiffelStudio: Melting Ice™ Technology
Fast recompilation: time depends on size of change, not size of program
Full type checking
“Freeze” once in a while
Optimized compilation: finalize.
Small program
Large program
Smallchange
Bigchange
19
Melting Ice Technology
FROZEN
MELTED
EiffelStudio Your system
Machine code(from C code)Edit, browse,
execute,debug, test…
Freeze
Melt
20
Performance
“Finalization” mode of compilation applies extensive optimizations:
Inlining Dead code removal Contract removal ...
Optimizations are compiler-applied and automatic; no need for manual hacking
Compacting garbage collection takes care of memory issues
Intended to match the most exacting demands of industry applications
21
EiffelStudio browsing and debugging
You are dealing with “development objects”:
Classes Features Run-time objects (for debugging)
To work on an object, “pick-and-drop” it into an appropriate tool
22
Openness
Eiffel can be used as “component combinator” to package elements from different sources:
Mechanisms for integrating elements in C, C++, Java, CIL (.NET)
Interfaces and libraries: SQL, XML, UML (XMI), CORBA, COM, others
Particularly sophisticated mechanisms for C/C++ interfacing
Outside of .NET, compiles down to ANSI C code, facilitates support for C and C++ easier.
On .NET, seamless integration with C#, VB .NET etc.
23
C/C++ support
Functions, macros, include files, setters, getters, constructors, destructors etc.
Inline C
From the outside into Eiffel: CECIL (C-Eiffel Common Interface Library)
24
Portability
Source-code portability across:
Windows NT, 2000, XP, Vista Windows 98, Me .NET Solaris, other commercial Unix variants Linux Mac OS X (forthcoming) BSD (Berkeley System Distribution) VMS
25
- 3 -
The method
26
The waterfall model of the lifecycle
Feasibility study
Requirements
Global design
Detailed design
Deployment
V & V
Specification
Implementation
27
Traditional lifecycle model
Rigid model:Waterfall: separate tasks,
impedance mismatchesVariants, e.g. spiral, retain
some of the problemsSeparate tools:
Programming environmentAnalysis & design tools, e.g. UML
Consequences:Hard to keep model, implementation,
documentation consistent Constantly reconciling viewsInflexible, hard to maintain systemsHard to accommodate bouts of late wisdomWastes effortsDamages quality
Feasibility study
Requirements
Global design
Detailed design
Deployment
V & V
Specification
Implementation
28
The Eiffel model
Seamless development:Single notation, tools, concepts, principles throughout Eiffel is as much for analysis & design as implementation & maintenanceContinuous, incremental developmentKeep model, implementation and documentation consistentReversibility: go back & forthSaves money: invest in single set of toolsBoosts quality
Example classes:PLANE, ACCOUNT, TRANSACTION…
STATE, COMMAND…
HASH_TABLE…
TEST_DRIVER…
TABLE…
Analysis
Design
Implemen-
tation
V&V
Generali-zation
29
Seamlessness
Seamlessness Principle
Software development should relyon a single set of notations & tools
30
Reversibility
Reversibility Principle
The software development process,notations and tools
should allow making changesat any step in the process
31
The seamless, reversible model
Example classes:PLANE, ACCOUNT, TRANSACTION…
STATE, COMMAND…
HASH_TABLE…
TEST_DRIVER…
TABLE…
Analysis
Design
Implemen-
tation
V&V
Generali-zation
32
Class invariant
Postcondition
Precondition
Specified, notimplemented
Analysis classesdeferred class VAT inherit
TANKfeature
in_valve, out_valve : VALVE
fill -- Fill the vat.
requirein_valve.openout_valve.closed
deferred
ensurein_valve.closed
out_valve.closedis_full
end
empty, is_full, is_empty, gauge, maximum,
invariantis_full = (gauge >= 0.97 * maximum) and (gauge <= 1.03 * maximum)
end
33
Single model
Use a single base for everything: analysis, design, implementation, documentation...
Use tools to extract the appropriate views.
Single Model Principle
All the informationabout a software system
should be in the software text
34
The seamless, reversible model
Analysis
Design
Implemen-
tation
V&V
Generali-zation
35
Generalization
Prepare for reuse:Remove built-in limitsRemove dependencies on specifics of project
Improve documentation, contracts...
Abstract Extract commonalities, revamp inheritance hierarchy
35
A D I V G
A *
B
Y *
X Z
T
U
36
The cluster model
A
D
I
V
G
Permits dynamic reconfiguration
A
D
I
V
G
A
D
I
V
G
A
D
I
V
G
A
D
I
V
G
A
D
I
V
G
Mix of sequential and concurrent engineering
37
Tool support for seamless development
Diagram Tool• System diagrams can be produced automatically from software text
• Works both ways: update diagrams or update text – other view immediately updated
No need for separate UML tool Metrics Tool Profiler Tool Documentation generation tool ...
38
EiffelStudio diagram tool
39
Text-graphics equivalence
40
Equivalence
Equivalence Principle
Textual, graphical and other viewsshould all represent the same model
41
Eiffel mechanisms
Classes, objects, ... Single and multiple inheritance Inheritance facilities: redefinition, undefinition,
renaming Genericity, constrained and unconstrained Safe covariance Disciplined exception handling, based on
principles of Design by Contract Full GC Agents (power of functional programming in O-O!) Unrestricted streaming: files, databases,
networks...
42
What is not in Eiffel
Goto Functions as arguments Pointer arithmetic Special increment syntax, e.g. x++, ++x
In-class feature overloading
43
Syntax conventions
Semicolon used as a separator (not terminator)It’s optional almost all the time. Just forget about it!
Style rules are an important part of Eiffel: Every feature should have a header comment Every class should have a note clause Layout, indentation Choice of names for classes and features
44
The class
From the module viewpoint: Set of available services (“features”) Information hiding Classes may be clients of each other
From the type viewpoint: Describes a set of run-time objects (the instances
of the class) Used to declare variables (more generally,
entities ), e.g. x : C
Possible type checking Notion of subtype
45
Information hiding
Information Hiding principle
Every module should have a publicspecification,
listing a subset of its properties
46
prepend
animate
append
An object has an interface
count stations
first last
47
prepend
animate
appendcount
first
An object has an implementation
count stations
first last
48
Information hiding
prepend
animate
appendcount stations
first last
49
Information Hiding
The designer of every module must select a subset of its properties as the official information about the module, made available to authors of client modules
Public
Private
50
Uniform access
Uniform access principle
It does not matter to the clientwhether you look up or compute
51
Uniform Access: an example
balance = list_of_deposits.total – list_of_withdrawals.total
(A1)200 100 500 1000
800 100 100
(A2)
200 300 500 1000
800 100 100
list_of_deposits
list_of_withdrawals
list_of_deposits
list_of_withdrawals
balance 1000
52
Uniform access
A call such as
your_account.balance
could use an attribute or a function
Uniform access principle
It does not matter to the clientwhether you look up or compute
53
POINT : as an abstract data type
x : POINT REAL
y : POINT REAL
: POINT REAL
: POINT REAL
Class POINT: Choose a representation (polar, cartesian)
In polar representation, and are attributes, x and y are routines.
y
x
54
POINT: as a class
class POINT feature
x, y : REAL-- Cartesian coordinates
move (a, b : REAL)-- Move by a horizontally and b vertically.
dox := x + ay := y + b
end
scale (factor : REAL)-- Scale by factor.
dox := factor * xy := factor * y
end
55
Class POINT
distance (p : POINT ): REAL-- Distance to p
doResult := sqrt ((x – p.x)^2 + (y –
p.y)^2)end
ro : REAL-- Distance to origin (0, 0)
doResult := sqrt (x ^ 2 + y ^ 2)
end
theta : REAL-- Angle to horizontal axis
do…
endend
56
Uniform access through feature call
To access a feature of a point, same notation regardless of representation.
Example:
p1.x
Cartesian representation: attribute call Polar representation: function call
No difference for clients (except possibly performance)
57
Uniform access in practice
Class COMPLEX, switching silently and on demand between cartesian and polar representation
Secret attributes:
cartesian_uptodate, polar_uptodate : BOOLEANinternal_x, internal_y, internal_ro, internal_theta :
REAL
Representation invariant:
invariantat_least_one : cartesian_uptodate or
polar_uptodate
58
Updating representation: secret routine
update_cartesianrequire
polar_ok: polar_uptodatedo
if not cartesian_uptodate theninternal_x := ro * cos (theta)internal_y := ro * sin (theta)
endensure
cart_ok: cartesian_uptodatepolar_ok: polar_uptodate
end
59
Public query
x : REAL -- Abscissa of current pointdo
if not cartesian_uptodate thenupdate_cartesian
endResult := x_internal
ensurecart_ok : cartesian_uptodate
same_as_internal : Result = x_internal
end
60
Adding two complex numbers
plus (other : COMPLEX )
-- Add other to current complex number. do
update_cartesian
x_internal := x_internal + other.xy_internal := y_internal + other.y
ensurecartesian_ok : cartesian_uptodate
end
61
Beyond information hiding
Single choice principle
If a system supports a set of choices,only one of its elements should know the list
62
Single choice: examples
Graphic system: set of figures
Editor: set of commands
Compiler: set of language constructs
Single choice principle
If a system supports a set of choices,only one of its elements should know the list
63
Without dynamic binding!
display (f : FIGURE )do
if ‘‘f is a CIRCLE’’ then ...
elseif ‘‘f is a POLYGON’’ then...
endend
and similarly for all other routines!
Tedious; must be changed whenever there’s a new figure type
64
With inheritance &associated techniques
f : FIGUREc : CIRCLEp : POLYGON
create c.make (...)create p.make (...)
if ... then f := c
else f := p
end
f.move (...)f.rotate (...)f.display (...)
-- and so on for every -- operation on f !
With:
Initialize:
and:
Then just use:
65
Memory management
Memory management principle
It is the implementation’s responsibilityto reclaim unused objects
66
What to do with unreachable objects
Reference assignmentsmay make some objects useless.
Two possible approaches: Manual “free” (C++). Automatic garbage collection
“Almaviva”namelandlor
dloved_one
aO1
“Figaro”O2
“Susanna”O3
67
The C programmer’s view
Newsgroup posting by Ian Stephenson, 1993 (as cited in Object-Oriented Software Construction, 2nd edition):
I say a big NO ! Leaving an unreferenced object around is BAD PROGRAMMING. Object pointers ARE like ordinary pointers — if you allocate an object you should be responsible for it, and free it when its finished with. (Didn't your mother always tell you to put your toys away when you'd finished with them?)
68
Arguments for automatic collection
Manual reclamation is dangerous for reliability.
Wrong “frees” are among the most difficult bugs to detect and correct.
Manual reclamation is tedious.
Modern garbage collectors have acceptable performance overhead.
GC is tunable: disabling, activation, parameterization....
69
Properties of a garbage collector (GC)
Soundness: If the GC reclaims an object, it is unreachable
Completeness : If an object is unreachable, the GC will reclaim it
Soundness is an absolute requirement. Better no GC than an unsound GC
But: safe automatic garbage collection is hard in C-based languages
70
Language style
Consistency principle
The language should offerone good way to do anything useful
71
Language style
Compatibility principle
Traditional notations should be supportedwith an O-O semantics
72
Infix and prefix operators
In
a − bthe − operator is “infix”
(written between operands)
In
− bthe − operator is “prefix”
(written before the operand)
73
The object-oriented form of call
some_target.some_feature (some_arguments)
For example:
my_figure.display
my_figure.move (3, 5)
x := a.plus (b) ???????
74
Operator features
expanded class INTEGER feature
plus alias "+" (other : INTEGER): INTEGER-- Sum with other
do ... end
times alias "*" (other : INTEGER): INTEGER -- Product by other
do ... end
minus alias "-" : INTEGER-- Unary minus
do ... end...end
Calls such as i.plus ( j ) can now be written i + j
75
Assignment commands
It is possible to define a query as
temperature: REAL assign set_temperature
Then the syntax
x.temperature := 21.5
is accepted as an abbreviation for
x.set_temperature (21.5)
Retains contracts and any other supplementary operations
Not an assignment, but a procedure call
76
Array access
Object-oriented forms:a : ARRAY [T ]a.put (x, 23)x := a.item (23)
Usual forms:a [23] := x
x := a [23]
Usual form:a [i ] := a [i ] + 1
Object-oriented form:a.put (a.item (i ) + 1, i )
77
Using the bracket alias
In class ARRAY [G ] :
item (i : INTEGER): Grequire
i >= lower and i <= countdo … end
put (x : G ; i : INTEGER): Grequire
i >= lower and i <= countdo … end
alias "[ ]" assign put
a.put (a.item (i ) + 1, i )
a.item (i ) := a.item (i ) + 1
a [i ] := a [i ] + 1
Not an assignment!
78
Bracket alias
population [“Lugano ] := 50000
table [a, b, c] := d
79
Command-query separation
Command-Query Separation Principle
A function must not changeits target object’s abstract state
80
Command-Query separation
A command (procedure) does something but does not return a result.
A query (function or attribute) returns a result but does not change the state.
81
Command-Query Separation
Asking a questionshould not change the answer!
82
Command-query separation
Command-Query Separation Principle
A function must not changeits target object’s state
This principle excludes many common schemes, such as using functions for input (e.g. C’s getint or equivalent).
83
Referential transparency
If two expressions have equal value, one may be substituted for the other in any context where that other is valid.
If a = b, then f (a) = f (b) for any f. Prohibits functions with side effects. Also:
For any integer i, normally i + i = 2 x i But even if getint () = 2, getint () + getint () is
usually not equal to 4.
84
Command-query separation
Input mechanism using EiffelBase(instead of n := getint ()):
io.read_integer
n := io.last_integer
85
A discipline of development
Reuse Principle
Design with reuse in mind
86
Typical API in a traditional library (NAG)
nonlinear_ode(equation_count : in INTEGER; epsilon : in out DOUBLE; func : procedure
(eq_count : INTEGER; a : DOUBLE; eps : DOUBLE; b : ARRAY [DOUBLE]; cm : pointer Libtype);
left_count, coupled_count : INTEGER …)
[And so on. Altogether 19 arguments, including: 4 in out values; 3 arrays, used both as input and output; 6 functions, each with 6 or 7 arguments, of
which 2 or 3 arrays!]
Ordinary differential equation
87
The EiffelMath routine
... Create e and set-up its values (other than defaults) ...
e.solve
... Answer available in e.x and e.y ...
88
The Consistency Principle
Two components: Top-down and deductive (the overall design). Bottom-up and inductive (the conventions).
Consistency Principle
All the components of a libraryshould proceed from an overall
coherent design, and followa set of systematic, explicitand uniform conventions.
89
The key to building a library
Devising a theory of the underlying domain
90
Some of the theory behind EiffelBase
CONTAINER
BOX
FINITE INFINITE
BOUNDED UNBOUNDED
FIXED RESIZABLE
COLLECTION
BAG SET
TABLE ACTIVE SUBSET
DISPENSERINDEXABLE CURSOR_STRUCTURE
SEQUENCE
TRAVERSABLE
HIERAR_CHICAL LINEAR
BILINEAR
*
* * *
*
*
*
*
* *
* * * * * *
* * * * * *
COUNTABLE*
RepresentationAccess
Iteration
91
The size of feature interfaces
More relevant than class size for assessing complexity.
Statistics from EiffelBase and associated libraries:
Number of features 4408
Percentage of queries 66%
Percentage of commands 34%
Average number of arguments to a feature 0.5
Maximum number 5
No arguments 57%
One argument 36%
Two arguments 6%
Three or more arguments 1%
92
Operands and options
Two possible kinds of argument to a feature: Operands: values on which feature will operate Options: modes that govern how feature will
operateExample (non-O-O): printing a real number print (real_value, number_of_significant_digits,
zone_length, number_of_exponent_digits, ...)The number is an operand; format properties (e.g. number of significant digits, width) are options
O-O example:
my_window.display (x_position, y_position, height, width, text, title_bar_text, color, ...)
93
Recognizing options from operands
Two criteria to recognize an option:
There is a reasonable default value.
During the evolution of a class, operands will normally remain the same, but options may be added.
94
Option-Operand separation
Option values: Defaults (specified universally, per type, per
object) To set specific values, use appropriate “setter”
procedures
Example:
my_window.set_background_color ("blue")...
my_window.display
Option-Operand Principle
Only operands should appearas arguments of a feature
95
Naming (classes, features, variables…)
Traditional advice (for ordinary application programming):
Choose meaningful variable names!
96
enter
push
add
insert
Original
Class
ARRAY
STACK
QUEUE
HASH_TABLE
entry
top
oldest
value
pop
remove_oldest
delete
Features
names for EiffelBase classes
put
put
put
put
item
item
item
item
remove
remove
remove
Final
enter
push
add
insert
Class
ARRAY
STACK
QUEUE
HASH_TABLE
remove_oldest
delete
Features
put
put
put
item
item
item
item
remove
remove
remove
entry
top
oldest
value
put
New and old names for EiffelBase classes
97
Naming rules
Achieve consistency by systematically using a set of standardized names.
Emphasize commonality over differences.
Differences will be captured by: Signatures (number and types of arguments &
result) Assertions Comments
98
Some standard namesQueries (non-boolean):
count, capacityitem
to_X, from_X
Queries (boolean) :writable, readable, extendible, prunableis_empty, is_full
-- Usual invariants:0 <= count ; count <= capacityis_empty = (count = 0) ; is_full = (count =
capacity)
if s.deletable thens.delete (v)
end
-- Some rejected names:
if s.addable thens.add (v)
end
Commands:put, extend, replace, forcewipe_out, remove, prunemake -- For creation
99
- 4 -
Design by Contract
100
Design by Contract
Contract Principle
Every software elementshould be characterized
by a precise specification
101
Design by Contract: applications
Getting the software right Analysis Design Implementation Debugging Testing Management Maintenance Documentation
102
Design by Contract: the basic idea
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
103
A counter-example: Ariane 5, 1996
(See: Jean-Marc Jézéquel and Bertrand Meyer: Design by Contract: The Lessons of Ariane, IEEE Computer, January 1997, also at http://www.eiffel.com)
37 seconds into flight, exception in Ada program not processed; order given to abort the mission. Ultimate cost in billions of euros
Cause: incorrect conversion of 64-bit real value (“horizontal bias” of the flight) into 16-bit integer
Systematic analysis had “proved” that the exception could not occur!
104
Ariane-5 (continued)
It was a REUSE error:
The analysis was correct – for Ariane 4 !
The assumption was documented – in a design document !
With assertions, the error would almost certainly detected by either static inspection or testing:
integer_bias (b : REAL): INTEGER
requirerepresentable (b)
do…
ensureequivalent (b, Result)
end
105
The contract view of software construction
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
106
Contracts for analysis
Client
Supplier
(Satisfy precondition:)
Make sure input valve is open, output valve closed
(Satisfy postcondition:)
Fill the tank and close both valves
OBLIGATIONS
(From postcondition:)
Get filled-up tank, with both valves closed
(From precondition:)
Simpler processing thanks to assumption that valves are in the proper initial position
BENEFITSfill
107
Class invariant
Postcondition
Precondition
Specified, notimplemented
Constracts for analysis
deferred class VAT inherit
TANKfeature
in_valve, out_valve : VALVE
fill -- Fill the vat.
requirein_valve.openout_valve.closed
deferred
ensurein_valve.closed
out_valve.closedis_full
end
empty, is_full, is_empty, gauge, maximum,
invariantis_full = (gauge >= 0.97 * maximum) and (gauge <= 1.03 * maximum)
end
108
A class without contracts
classACCOUNT
feature -- Access
balance : INTEGER-- Balance
Minimum_balance: INTEGER = 1000-- Minimum balance
feature {NONE } -- Deposit and withdrawal
add (sum : INTEGER)-- Add sum to the balance.
dobalance := balance + sum
end
Secret features
109
A class without contracts
feature -- Deposit and withdrawal operations
deposit (sum : INTEGER)-- Deposit sum into the account.
doadd (sum)
end
withdraw (sum : INTEGER)-- Withdraw sum from the account.
doadd (– sum)
end
may_withdraw (sum : INTEGER): BOOLEAN-- Is it permitted to withdraw sum from the
account?do
Result := (balance - sum >= Minimum_balance)
endend
110
Introducing contracts
classACCOUNT
create
make
feature {NONE } -- Initializationmake (initial_amount: INTEGER)
-- Set up account with initial_amount.
require
large_enough: initial_amount >= Minimum_balance
dobalance := initial_amount
ensure
balance_set: balance = initial_amountend
111
Introducing contracts
feature -- Access
balance: INTEGER-- Balance
Minimum_balance : INTEGER = 1000-- Lowest permitted balance
feature {NONE} -- Implementation of deposit and withdrawal
add (sum : INTEGER)-- Add sum to the balance.do
balance := balance + sum ensure
increased: balance = old balance + sum end
112
Introducing contracts
feature -- Deposit and withdrawal operations
deposit (sum : INTEGER)-- Deposit sum into the account.
requirenot_too_small: sum >= 0
doadd (sum)
ensureincreased: balance = old balance +
sumend
Precondition
Postcondition
113
Introducing contracts
withdraw (sum : INTEGER)-- Withdraw sum from the account.
requirenot_too_small: sum >= 0not_too_big: sum <= balance –
Minimum_balancedo
add (–sum)
-- i.e. balance := balance – sumensure
decreased: balance = old balance - sum
endValue of balance, captured on entry to routine
114
The contract
Client
Supplier
(Satisfy precondition:)
Make sure sum is neither too small nor too big
(Satisfy postcondition:)
Update account for withdrawal of sum
OBLIGATIONS
(From postcondition:)
Get account updated with sum withdrawn
(From precondition:)
Simpler processing: may assume sum is within allowable bounds
BENEFITSwithdraw
115
The imperative and the applicative
do
balance := balance - sum
ensure
balance = old balance - sum
PRESCRIPTIVE DESCRIPTIVE
How?
Operational
Implementation
Command
Instruction
Imperative
What?
Denotational
Specification
Query
Expression
Applicative
116
Introducing contracts
may_withdraw (sum : INTEGER ): BOOLEAN-- Is it permitted to withdraw sum from
account?do
Result := (balance - sum >= Minimum_balance)
end
invariantnot_under_minimum: balance >= Minimum_balance
end
117
The class invariant
Consistency constraint applicable to all instances of a class.
Must be satisfied: After creation After execution of any feature by any client
Qualified calls only: x.f (...)
118
The correctness of a class
For every creation procedure cp :
{Precp } docp {INV and Postcp }
For every exported routine r :
{INV and Prer } dor {INV and Postr }
x.f (…)
x.g (…)
x.h (…)
create x.make (…) S1
S2
S3
S4
119
Uniform Access
balance = deposits.total – withdrawals.total
(A1)list_of_deposits
list_of_withdrawals
200 100 500 1000
800 100 100
(A2)
200 300 500 1000
800 100 100
list_of_deposits
list_of_withdrawals
balance 1000
120
What are contracts good for?
Writing correct software (analysis, design, implementation, maintenance, reengineering) Documentation (the “contract” form of a class)Effective reuseControlling inheritancePreserving the work of the best developers
Quality assurance, testing, debugging (especially in connection with the use of libraries) Exception handling
121
A contract violation is not a special case
For special cases(e.g. “if the sum is negative, report an error...”)
use standard control structures, such as if ... then ... else...
A run-time assertion violation is something else: the manifestation of
A DEFECT (“BUG”)
122
Contracts and quality assurance
Precondition violation: Bug in the client.
Postcondition violation: Bug in the supplier.
Invariant violation: Bug in the supplier.
{P } A {Q }
123
Contracts: run-time effect
Compilation options (per class, in Eiffel): No assertion checking Preconditions only Preconditions and postconditions Preconditions, postconditions, class invariants All assertions
124
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
125
Lists in EiffelBase
Cursor
item
index
count1
forthback
finishstart
afterbefore
“Munich"
126
Trying to insert too far right
Cursor
(Already past last element!)
count1
after
"Munich"
127
A command and its contract
Precondition
Postcondition
128
Moving the cursor forward
Cursor
index
forth
count1
afterbefore
"Munich"
129
Two queries, and command forth
130
Where the cursor may go
Valid cursor positions
0 index1
afterbefore
"Munich"
count count + 1
131
From the invariant of class LIST
Valid cursor positions
132
Contracts and bug types
Preconditions are particularly useful to find bugs in client code:
YOUR APPLICATION
COMPONENT LIBRARY
your_list.insert (y, a + b + 1)
i <= count + 1
insert (x : G ; i : INTEGER)require
i >= 0
class LIST [G ] feature
133
Contracts and quality assurance
Use run-time assertion monitoring for quality assurance, testing, debugging.
Compilation options (reminder):
No assertion checking Preconditions only Preconditions and postconditions Preconditions, postconditions, class invariants All assertions
134
Contracts and quality assurance
Contracts enable QA activities to be based on a precise description of what they expect.
Profoundly transform the activities of testing, debugging and maintenance.
“I believe that the use of Eiffel-like module contracts is the most important non-practice in software world today. By that I mean there is no other candidate practice presently being urged upon us that has greater capacity to improve the quality of software produced. ... This sort of contract mechanism is the sine-qua-non of sensible software reuse. ”
Tom de Marco, IEEE Computer, 1997
135
Contracts and documentation
Contract view: 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,
invariant Remove any contract clause that refers to a secret
feature(This raises a problem; can you see it?)
136
Flat, interface
Flat view of a class: reconstructed class with all the features at the same level (immediate and inherited). Takes renaming, redefinition etc. into account.
The flat view is an inheritance-free client-equivalent form of the class.
Interface view: the contract view of the flat view. Full interface documentation.
137
Uses of the contract &interface forms
Documentation, manualsDesignCommunication between developersCommunication between developers and managers
138
Contracts and inheritance
Issues: what happens, under inheritance, to
Class invariants?
Routine preconditions and postconditions?
139
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.
140
Contracts and inheritance
require
ensure
rrequire
ensure
a1 : A
a1.r (…)
…
Correct call in C: if a1. then a1.r (...) -- Here a1. holds end
r ++
C A
D B
ClientInheritance ++ Redefinition
141
Assertion redeclaration rule
When redeclaring a routine, we may only:
Keep or weaken the precondition
Keep or strengthen the postcondition
142
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
143
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
144
Managerial benefits
Library users can trust documentation.They can benefit from preconditions to validate their own software.Test manager can benefit from more accurate estimate of test effort.Black-box specification for free.Designers who leave bequeath not only code but intent.Common vocabulary between all actors of the process: developers, managers, potentially customers.Component-based development possible on a solid basis.
145
Genericity and inheritance
LIST_OF_CARS
SET_OF_CARS
LINKED_LIST_OF_CARS
LIST_OF_CITIES
LIST_OF_PERSONS
Abstraction
Specialization
Type parameterization
Type parameterization
Genericity
Inheritance
146
Extending the basic notion of class
LIST_OF_CARS
SET_OF_CARS
LINKED_LIST_OF_CARS
LIST_OF_CITIES
LIST_OF_PERSONS
LINKED_LIST_OF_CITIES
SET_OF_PERSONS
Genericity
Inheritance
147
An inheritance hierarchy
center * display
*rotate *
perimeter *
perimeter+
perimeter+
perimeter+
+
diagonal
...
...
perimeter+
+
side2
* deferred
+ effective
++ redefined
perimeter+
+
side1
CLOSED_FIGURE
OPEN_FIGURE
FIGURE
SEGMENT POLYLINE
TRIANGLE
POLYGON
ELLIPSE
RECTANGLE
SQUARE
CIRCLE
side
*
**
148
Redefinition 1: polygons
class POLYGON inheritCLOSED_FIGURE
createmake
featurevertex : ARRAY [POINT]vertex_count : INTEGER perimeter : REAL
-- Perimeter lengthdo from ... until ... loop
Result := Result + vertex [i ] . distance (vertex [i + 1])
... endend
invariantvertex_count >= 3vertex_count = vertex.count
end
vertex [i ]
vertex [i + 1]
149
Redefinition 2: rectangles
class RECTANGLE inheritPOLYGON
redefine perimeter
endcreate
make
featurediagonal, side1, side2 : REAL
perimeter : REAL-- Perimeter length
do Result := 2 * (side1 + side2) endinvariant
vertex_count = 4end
side1
side2diagonal
150
Inheritance, typing &polymorphism
(POLYGON )
(RECTANGLE )
p
r
Assume: p : POLYGON ; r : RECTANGLE ; t : TRIANGLE ; x : REAL
Permitted:
x := p.perimeterx := r.perimeterx := r.diagonalp := r
NOT permitted:
x := p.diagonal -- Even just after p := r ! r := p
151
Definitions: Polymorphism
An attachment (assignment or argument passing) is polymorphic if its target variable and source expression have different types.
An entity or expression is polymorphic if it may at runtime — as a result of polymorphic attachments —become attached to objects of different types.
Polymorphism is the existence of these possibilities.
152
Dynamic binding
What is the effect of this (assuming some_test true)?
if some_test thenp := r
elsep := t
end
x := p.perimeter
Redefinition: A class may change an inherited feature, as with POLYGON redefining perimeter
Polymorphism: p may have different forms at run-time.
Dynamic binding: Effect of p.perimeter depends on run-time form of p
153
Definitions (Dynamic binding)
Dynamic binding (a semantic rule) is the property that any execution of a feature call will use the version of the feature best adapted to the type of the target object.
154
Without dynamic binding!
display (f : FIGURE )do
if ‘‘f is a CIRCLE’’ then ...
elseif ‘‘f is a POLYGON’’ then...
endend
and similarly for all other routines!
Tedious; must be changed whenever there’s a new figure type
155
With inheritance &associated techniques
f : FIGUREc : CIRCLEp : POLYGON
create c.make (...)create p.make (...)
if ... then f := c
else f := p
end
f.move (...)f.rotate (...)f.display (...)
-- and so on for every -- operation on f !
With:
Initialize:
and:
Then just use:
156
Extending the basic notion of class
LIST_OF_CARS
SET_OF_CARS
LINKED_LIST_OF_CARS
LIST_OF_CITIES
LIST_OF_PERSONS
Abstraction
Specialization
Type parameterization
Type parameterization
Genericity
Inheritance
157
Genericity
Unconstrained
LIST [G]e.g. LIST [INTEGER], LIST [PERSON]
Constrained
HASH_TABLE [G ―> HASHABLE ]
VECTOR [G ―> NUMERIC ]
158
Genericity: Ensuring type safety
How can we define consistent “container” data structures, e.g. list of accounts, list of points? Dubious use of a container data structure:
c : CITY ; p : PERSONcities : LIST ... people : LIST ... ---------------------------------------------------------people.extend ( )
cities.extend ( )
c := cities.last
c. some_city_operation
What if wrong?
p
c
159
A generic class
class LIST [G ] feature
extend (x : G ) ...
last : G ...
end
To use the class: obtain a generic derivation, e.g.
cities : LIST [CITY ]
Formal generic parameter
Actual generic parameter
160
Using generic derivations
cities : LIST [CITY ]people : LIST [PERSON]c : CITYp : PERSON...
cities.extend (c)people.extend (p)
c := cities.last
c. some_city_operation
STATIC TYPING
The compiler will reject:
people.extend (c)
cities.extend (p)
161
Static typing
Type-safe call (during execution):
A feature call x.f such that the object attached to x has a feature corresponding to f.
[Generalizes to calls with
arguments, x.f (a, b) ]
Static type checker:A program-processing tool (such as a compiler) that guarantees, for any program it accepts, that any call in any execution will be type-safe.
Statically typed language:A programming language for which it is possible to write a static type checker.
162
Using genericity
LIST [CITY ]LIST [LIST [CITY ]]…
A type is no longer exactly the same thing as a class!
(But every type remains based on a class.)
163
Genericity + inheritance 1: Constrained genericity
class VECTOR [G ] feature plus alias "+" (other : VECTOR [G]): VECTOR [G]
-- Sum of current vector and otherrequire
lower = other.lower
upper = other.upperlocal
a, b, c: Gdo
... See next ...end
... Other features ...end
164
Adding two vectors
i a b c=+
+ =u v w
1
2
165
Constrained genericity
Body of plus alias "+":
create Result.make (lower, upper)
from i := lower
until i > upper
loopa := item (i)b := other.item (i)c := a + b -- Requires “+” operation on G!
Result.put (c, i)i := i + 1
end
166
The solution
Declare class VECTOR as
class VECTOR [G –> NUMERIC ] feature
... The rest as before ...end
Class NUMERIC (from the Kernel Library) provides features plus alias "+", minus alias "-"and so on.
167
Improving the solution
Make VECTOR itself a descendant of NUMERIC,
effecting the corresponding features:
class VECTOR [G –> NUMERIC ] inheritNUMERIC
feature... Rest as before, including infix "+"...
endThen it is possible to define
v : VECTOR [INTEGER ]vv : VECTOR [VECTOR [INTEGER ]]vvv : VECTOR [VECTOR [VECTOR [INTEGER ]]]
168
Extending the basic notion of class
LIST_OF_CARS
SET_OF_CARS
LINKED_LIST_OF_CARS
LIST_OF_CITIES
LIST_OF_PERSONS
LINKED_LIST_OF_CITIES
SET_OF_PERSONS
Genericity
Inheritance
169
Genericity + inheritance 2: Polymorphic data structures
figs : LIST [FIGURE ]p1, p2 : POLYGONc1, c2 : CIRCLEe : ELLIPSE
(POLYGON) (CIRCLE) (POLYGON)(CIRCLE) (ELLIPSE)
class LIST [G ] featureextend (v : G) do
… endlast : G…
end
figs.extend (p1 ) ; figs.extend (c1 ) ; figs.extend (c2 )
figs.extend (e ) ; figs.extend (p2 )
170
Combining abstractions
Given the classes
TRAIN_CAR, RESTAURANT
how would you implement a DINER ?
171
Examples of multiple inheritance
Combining separate abstractions:
Restaurant, train car Calculator, watch Plane, asset Home, vehicle Tram, bus
172
Composite figures
173
Multiple inheritance: Composite figures
A composite figure
Simple figures
174
Defining the notion of composite figure
COMPOSITE_FIGURE
centerdisplayhiderotatemove…
countputremove…
FIGURELIST
[FIGURE ]
175
In the overall structure
COMPOSITE_FIGURE
FIGURELIST [FIGURE ]
OPEN_FIGURE
CLOSED_FIGURE
SEGMENT POLYLINE POLYGON ELLIPSE
RECTANGLE
SQUARE
CIRCLE
TRIANGLE
perimeter+
perimeter*
perimeter++
diagonal
perimeter++
perimeter++
perimeter+
176
A composite figure as a list
Cursor
item
forth
after
177
Composite figures
class COMPOSITE_FIGURE inheritFIGURE
LIST [FIGURE]feature
display-- Display each constituent figure in turn.
dofrom start until after loop
item.display
forth endend... Similarly for move, rotate etc. ...
end
Requires dynamic binding
178
Multiple inheritance: Combining abstractions
COMPARABLE NUMERIC
STRING COMPLEX
INTEGER
REAL
<, <=, >, >=, …
+, –, *, / …(total order
relation)(commutative ring)
179
Renaming
‘‘Graphical’’ features: height, width, change_height, change_width, xpos, ypos, move...‘‘Hierarchical’’ features: superwindow, subwindows, change_subwindow, add_subwindow...
class WINDOW inheritRECTANGLETREE [WINDOW]
renameparent as superwindow,children as subwindows,add_child as add_subwindow…
endfeature
...end
BUT: see style rules about
uniformity of feature names
180
- 5 -
Some newdevelopments
181
Some recent developments
Void safety
Automatic testing
Concurrency
182
Basic O-O operation…
x.f (args)
… and basic issue studied here:
(If not, call produces an exception and usually termination)
Semantics: apply the feature f, with given args if any, to the object to which x is attached
How do we guarantee that x will always be “attached” to an object?
183
Void safety: requirements
Statically, completely void safe: no exceptions
Handles genericity
Simple for programmer, no mysterious rules
Reasonably simple for compiler
Compatibility or minimum change for existing
code
(Plus for me: 1st semester teachability)
184
Components of the solution
1. Some patterns guaranteed void-safe(“Certified Attachment Patterns” or CAPS)
2. Void value permitted only for types declared as “detachable”. By default types are “attached”
3. Initialization rules ensure that any variable of an attached type has a non-void initialization value
4. Special rules for arrays
185
Automatic testing
Two tools: AutoTest: takes a set of classes and tests them
automatically (push-button, no manual test cases, no test oracles, nothing…)
CDD (Contract-Driven Development): automatically extracts test cases from execution failures
Integrated into EiffelStudio 6.3 and 6.4
186
Caveat
I am mostly talking about:
Functional testing
Unit testing
187
What is testing about?
To test a software system is to try to make it fail
Testing is none of:Ensuring software qualityAssessing software
qualityDebugging
(Terminology: failure, fault, mistake)Fiodor Chaliapineas Mephistopheles
“Ich bin der Geist, der stets verneint”
Goethe, Faust, Act I
188
1. To test a program is to try tomake it fail
2. Tests are no substitute forspecifications
3. Any failed execution must yield a test case, to remain forever remain part of the regression test base
4. Determining success or failure (oracles) must be automatic
4’: Oracles should be part of the program, as contracts5. A test suite must include both manual and automated cases6. Don’t believe your testing insights: evaluate any testing
strategy through objective criteria7. The most important criterion is number of faults found against
time: fc (t)
Seven principles of software testing
Bertrand Meyer, Seven Principles of Software Testing, IEEE Computer, August 2008
189189
“Automated testing”
What can be automated: Test suite execution Resilience Regression testing Test case generation Test result verification (oracles) Test case minimization
190190
Contracts for testing
Contracts provide the right basis: A fault is a discrepancy between intent and reality Contracts describe intent
A contract violation always signals a fault: Precondition: in client Postcondition or invariant: in routine (supplier)
In EiffelStudio: select compilation option for contract monitoring at level of class, cluster or system.
191
AutoTest: automatic test framework
Input: set of classes + testing time Generates instances, calls routines with
automaticallyselected arguments
Oracles are contracts: Direct precondition violation: skip Postcondition/invariant violation: bingo!
Value selection: Random+ (use special values such as 0, +/-1, +/-10, max and min)
Add manual tests if desired Any test (manual or automated) that fails becomes
part of the test suite
Ilinca CiupaAndreas Leitner
(SOFSEM 2007 etc.)
192
Minimization through dynamic slicing
auto_test system.ace –t 120 ACCOUNT CUSTOMER
create {STRING} v1
v1.wipe_out
v1.append_character (’c’)
v1.append_double (2.45)create {STRING} v2
v1.append_string (v2)
v2.fill (’g’, 254343)...create {ACCOUNT} v3.make (v2)v3.deposit (15)
v3.deposit (100)
v3.deposit (-8901)...
classACCOUNT
createmake
featuremake (n :
STRING)
require
n /= Void
do
name := n
balance := 0
ensure
name = n
balance = 0end
name : STRING
balance : INTEGERdeposit (v : INTEGER) do
balance := balance + v
ensure balance = old balance + v
endinvariant name /= Void balance >= 0end
193193
AutoTest strategies
Object pool Get objects through creation procedures
(constructors) Diversify through procedures
Routine arguments Basic values: heuristics for each type
Objects: get from pool
Test all routines, including inherited ones (“Fragile base class” issue)
194
Random testing: example bug found
*SET
**
+SET1
+SET2
+ +
Test:s1, s2 : SETs2 s1
*: Deferred +: Effective
Bernd Schoeller
195
195
Some AutoTest results (random strategy)
Library Total Failed Total Failed
EiffelBase (Sep 2005) 40,000 3% 2000 6%
Gobo Math 1500 1% 140 6%
TESTS ROUTINES
196
Testing results and strategy
“Smart” ideas not always better
Don’t believe your intuitionMeasure and assess
objectively
fc (t)
Class STRING
Define good assessment criteria: Number of faults found Time to find all faults
Time
Experimental law:
fc (t ) = a – b / t
197
Fault categories
Specification faults -- examples: Precondition:
Missing non-voidness precondition (will go away) Missing min-max precondition Too strong precondition
Postcondition: Missing Wrong
Implementation faults -- examples: Faulty supplier Missing implementation Case not treated Violating a routine’s precondition Infinite loop
198
Who finds what faults?
On a small EiffelBase subset,we compared:
AutoTest Manual testing (students) (3 classes, 2 with bugs
seeded) User reports from the field
AutoTest: 62% specification, 38% implementationUser reports: 36% specification, 64% implementation
I.Ciupa, A. Leitner,M.Oriol, A. Pretschner
(submitted)
199
AutoTest vs manual testers
On three classes (two with seeded bugs): Humans found 14 faults, AutoTest 9 of them AutoTest found 2 faults that humans did not (in
large class) 3 faults not found by AutoTest found by 60% of
humans (one is infinite loop) 2 faults not found by AutoTest are missing
preconditions (void, min-max)
200
AutoTest vs user reports
On 39 EiffelBase classes: AutoTest found 85 faults,
Plus 183 related to RAW_FILE,PLAIN_TEXT_FILE, DIRECTORY (total 268)
4 of these also reported by users 21 faults solely reported by users 30% of AutoTest-found bugs related to extreme values;
users never report them
AutoTest finds only 1 out of 18 (5%) of implementation faults and 3 out of 7 specification faults
AutoTest bad at over-strong preconditions, wrong operator semantics, infinite loops, missing implementations
Users never find faulty suppliers (blame on client)
201
AutoTest developments
Large-scale extensive tests, empirical assessment of criteria & strategies
Comparison with manual efforts Complete integration with EiffelStudio IDE Background, unobtrusive, continuous testing Distributed cooperative testing (“Testi@home”)
202
CDD (Contract-Driven Development)
Like Test-Driven Development, but Tests derived from spec (contracts) Not the other way around!
Record every failed execution, make it reproducible by retaining objects
Turn it into a regression test
203
Specified but unimplemented routine
204
Running the system and entering input
(erroneous
)
20
205
Postcondition violated
The violated clause:
balance > old balance
Error caught at run time as contract violation
206
This has become a test case
206
207
Correcting and recompiling
208
One fault corrected, the other not
209
Test tools: lessons
1. Testing should be automatic
2. You need built-in contracts as in Eiffel
3. Testing is one of the tools for verification
4. Testing should be continuous and unobtrusive
210
Concurrency: the SCOOP model
General-purposeMulti-threading, Web services, distribution, multiprogramming...Simplifies concurrent programmingBased on Design by Contract ideas
211
Summary
Bring every one of your development
days
to the level of your best days
212
Gustave Eiffel, 1885
Must it be assumed that because we are engineers beauty is not our concern, and that while we make our constructions robust and durable we do not also strive to make them elegant? Is it not true that the genuine conditions of strength always comply with the secret conditions of harmony?
The first principle of architectural esthetics is that the essential lines of a monument must be determined by a perfect adaptation to its purpose.
Gustave Eiffel, 1887From his response in Le Temps to a petition by members of the literary and artistic Establishment protesting his project of elevating a tower of iron in Paris