Presentation is loading. Please wait.

Presentation is loading. Please wait.

Eiffel in Depth Bertrand Meyer With material by Emmanuel Stapf (Eiffel Software) & members of the ETH Chair of Software Engineering Chair of Software.

Similar presentations


Presentation on theme: "Eiffel in Depth Bertrand Meyer With material by Emmanuel Stapf (Eiffel Software) & members of the ETH Chair of Software Engineering Chair of Software."— Presentation transcript:

1

2 Eiffel in Depth Bertrand Meyer With material by Emmanuel Stapf (Eiffel Software) & members of the ETH Chair of Software Engineering Chair of Software Engineering

3 2 Plan of these slides 1Overview 2The environment(s) 3 Method overview 4 Language basics 5 Dynamic model 6Genericity & inheritance 7Design by Contract 8 External interface 9Agents 10 Advanced design 11 Advanced mechanisms 12 Conclusion 13 Supplements

4 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

5 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

6 Overview

7 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

8 7 Language versions Eiffel 1, 1986 Classes, contracts, genericity, single and multiple inheritance, garbage collection, … Eiffel 2, 1988 (Object-Oriented Software Construction) Exceptions, constrained genericity Eiffel 3, (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 Attached types, conversion, assigner commands…

9 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

10 9 9 Some typical users Axa Rosenberg Investment management: from $2 billion to >$100 billion 2 million lines Chicago Board of Trade Price reporting system Eiffel + CORBA + Solaris + Windows + … Xontech (for Boeing) Large-scale simulations of missile defense Northrop-Grumman Swedish social security: accident reporting & management (Eiffel) Price Reporting System The Chicago Board of Trade See: eiffel.com

11 10 10 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

12 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...

13 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!)

14 13 Libraries Fundamental data structures and algorithms Portable graphics Internet, Web Lexical analysis, parsing Database interfaces

15 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

16 15 The Eiffel language: there is a hidden agenda That you forget it even exists

17 The environment

18 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 Jitter Eiffel 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...

19 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 Small change Big change

20 19 Melting Ice Technology FROZEN MELTED EiffelStudio Your system Machine code (from C code) Edit, browse, execute, debug, test… Freeze Melt

21 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

22 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

23 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.

24 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)

25 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

26 The method

27 26 The waterfall model of the lifecycle Feasibility study Requirements Global design Detailed design Deployment V & V Specification Implementation

28 27 Traditional lifecycle model Rigid model: Waterfall: separate tasks, impedance mismatches Variants, e.g. spiral, retain some of the problems Separate tools: Programming environment Analysis & design tools, e.g. UML Consequences: Hard to keep model, implementation, documentation consistent Constantly reconciling views Inflexible, hard to maintain systems Hard to accommodate bouts of late wisdom Wastes efforts Damages quality Feasibility study Requirements Global design Detailed design Deployment V & V Specification Implementation

29 28 The Eiffel model Seamless development: Single notation, tools, concepts, principles throughout Eiffel is as much for analysis & design as implementation & maintenance Continuous, incremental development Keep model, implementation and documentation consistent Reversibility: go back & forth Saves money: invest in single set of tools Boosts quality Example classes: PLANE, ACCOUNT, TRANSACTION… STATE, COMMAND… HASH_TABLE… TEST_DRIVER… TABLE… Analysis Design Implemen- tation V&V Generali- zation

30 29 Seamlessness Seamlessness Principle Software development should rely on a single set of notations & tools

31 30 Reversibility Reversibility Principle The software development process, notations and tools should allow making changes at any step in the process

32 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

33 32 Class invariant Postcondition Precondition Specified, not implemented Analysis classes deferred class VAT inherit TANK feature in_valve, out_valve : VALVE fill -- 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, invariant is_full = (gauge >= 0.97 * maximum) and (gauge <= 1.03 * maximum) end

34 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 information about a software system should be in the software text

35 34 The seamless, reversible model Analysis Design Implemen- tation V&V Generali- zation

36 35 Generalization Prepare for reuse: Remove built-in limits Remove dependencies on specifics of project Improve documentation, contracts... Abstract Extract commonalities, revamp inheritance hierarchy 35 A DIV G A *A *BY * XZ T U

37 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

38 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...

39 38 EiffelStudio diagram tool

40 39 Text-graphics equivalence

41 40 Equivalence Equivalence Principle Textual, graphical and other views should all represent the same model

42 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...

43 42 What is not in Eiffel Goto Functions as arguments Pointer arithmetic Special increment syntax, e.g. x++, ++x In-class feature overloading

44 43 Syntax conventions Semicolon used as a separator (not terminator) Its 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

45 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

46 45 Information hiding Information Hiding principle Every module should have a public specification, listing a subset of its properties

47 46 prepend animate append An object has an interface count stations first last

48 47 prepend animate append count first An object has an implementation count stations first last

49 48 Information hiding prepend animate append count stations first last

50 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

51 50 Uniform access Uniform access principle It does not matter to the client whether you look up or compute

52 51 Uniform Access: an example balance = list_of_deposits. total – list_of_withdrawals. total (A1) (A2) list_of_deposits list_of_withdrawals list_of_deposits list_of_withdrawals balance 1000

53 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 client whether you look up or compute

54 53 POINT : as an abstract data type x : POINT REAL y : POINT REAL : POINT REAL Class POINT: Choose a representation (polar, cartesian) In polar representation, and are attributes, x and y are routines. y x

55 54 POINT : as a class class POINT feature x, y : REAL -- Cartesian coordinates move (a, b : REAL) -- Move by a horizontally and b vertically. do x := x + a y := y + b end scale (factor : REAL) -- Scale by factor. do x := factor x y := factor y end

56 55 Class POINT distance (p : POINT ): REAL -- Distance to p do Result := sqrt ((x – p.x)^2 + (y – p.y)^2) end ro : REAL -- Distance to origin (0, 0) do Result := sqrt (x ^ 2 + y ^ 2) end theta : REAL -- Angle to horizontal axis do … end

57 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)

58 57 Uniform access in practice Class COMPLEX, switching silently and on demand between cartesian and polar representation Secret attributes: cartesian_uptodate, polar_uptodate : BOOLEAN internal_x, internal_y, internal_ro, internal_theta : REAL Representation invariant: invariant at_least_one : cartesian_uptodate or polar_uptodate

59 58 Updating representation: secret routine update_cartesian require polar_ok: polar_uptodate do if not cartesian_uptodate then internal_x := ro cos (theta) internal_y := ro sin (theta) end ensure cart_ok: cartesian_uptodate polar_ok: polar_uptodate end

60 59 Public query x : REAL -- Abscissa of current point do if not cartesian_uptodate then update_cartesian end Result := x_internal ensure cart_ok : cartesian_uptodate same_as_internal : Result = x_internal end

61 60 Adding two complex numbers plus (other : COMPLEX ) -- Add other to current complex number. do update_cartesian x_internal := x_internal + other. x y_internal := y_internal + other. y ensure cartesian_ok : cartesian_uptodate end

62 61 Beyond information hiding Single choice principle If a system supports a set of choices, only one of its elements should know the list

63 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

64 63 Without dynamic binding! display (f : FIGURE ) do if f is a CIRCLE then... elseif f is a POLYGON then... end and similarly for all other routines! Tedious; must be changed whenever theres a new figure type

65 64 With inheritance &associated techniques f : FIGURE c : CIRCLE p : 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:

66 65 Memory management Memory management principle It is the implementations responsibility to reclaim unused objects

67 66 What to do with unreachable objects Reference assignments may make some objects useless. Two possible approaches: Manual free (C++). Automatic garbage collection Almavivaname landlord loved_one a O1 Figaro O2 Susanna O3

68 67 The C programmers view Newsgroup posting by Ian Stephenson, 1993 (as cited in Object-Oriented Software Construction, 2 nd 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?)

69 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....

70 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

71 70 Language style Consistency principle The language should offer one good way to do anything useful

72 71 Language style Compatibility principle Traditional notations should be supported with an O-O semantics

73 72 Infix and prefix operators In a b the operator is infix (written between operands) In b the operator is prefix (written before the operand)

74 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) ???????

75 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

76 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

77 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 )

78 77 Using the bracket alias In class ARRAY [G ] : item (i : INTEGER): G require i >= lower and i <= count do … end put (x : G ; i : INTEGER): G require i >= lower and i <= count do … 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!

79 78 Bracket alias population [Lugano ] := table [a, b, c] := d

80 79 Command-query separation Command-Query Separation Principle A function must not change its target objects abstract state

81 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.

82 81 Command-Query Separation Asking a question should not change the answer!

83 82 Command-query separation Command-Query Separation Principle A function must not change its target objects state This principle excludes many common schemes, such as using functions for input (e.g. Cs getint or equivalent).

84 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.

85 84 Command-query separation Input mechanism using EiffelBase (instead of n := getint ()): io. read_integer n := io. last_integer

86 85 A discipline of development Reuse Principle Design with reuse in mind

87 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

88 87 The EiffelMath routine... Create e and set-up its values (other than defaults)... e. solve... Answer available in e. x and e. y...

89 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 library should proceed from an overall coherent design, and follow a set of systematic, explicit and uniform conventions.

90 89 The key to building a library Devising a theory of the underlying domain

91 90 Some of the theory behind EiffelBase Representation Access Iteration

92 91 The size of feature interfaces More relevant than class size for assessing complexity. Statistics from EiffelBase and associated libraries: Number of features4408 Percentage of queries66% Percentage of commands34% Average number of arguments to a feature0.5 Maximum number5 No arguments57% One argument36% Two arguments6% Three or more arguments1%

93 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 operate Example (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,...)

94 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.

95 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 appear as arguments of a feature

96 95 Naming (classes, features, variables…) Traditional advice (for ordinary application programming): Choose meaningful variable names!

97 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 item remove Final enter push add insert Class ARRAY STACK QUEUE HASH_TABLE remove_oldest delete Features put item remove entry top oldest value put New and old names for EiffelBase classes

98 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

99 98 Some standard names Queries (non-boolean): count, capacity item to_X, from_X Queries (boolean) : writable, readable, extendible, prunable is_empty, is_full -- Usual invariants: 0 <= count ; count <= capacity is_empty = (count = 0) ; is_full = (count = capacity) if s. deletable then s. delete (v) end -- Some rejected names: if s. addable then s. add (v) end Commands: put, extend, replace, force wipe_out, remove, prune make -- For creation

100 Design by Contract

101 100 Design by Contract Contract Principle Every software element should be characterized by a precise specification

102 101 Design by Contract: applications Getting the software right Analysis Design Implementation Debugging Testing Management Maintenance Documentation

103 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 elements contract The contract of any software element should be Explicit Part of the software element itself

104 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 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!

105 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 require representable (b) do … ensure equivalent (b, Result) end

106 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

107 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 BENEFITS fill

108 107 Class invariant Postcondition Precondition Specified, not implemented Constracts for analysis deferred class VAT inherit TANK feature in_valve, out_valve : VALVE fill -- 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, invariant is_full = (gauge >= 0.97 * maximum) and (gauge <= 1.03 * maximum) end

109 108 A class without contracts class ACCOUNT feature -- Access balance : INTEGER -- Balance Minimum_balance: INTEGER = Minimum balance feature {NONE } -- Deposit and withdrawal add (sum : INTEGER) -- Add sum to the balance. do balance := balance + sum end Secret features

110 109 A class without contracts feature -- Deposit and withdrawal operations deposit (sum : INTEGER) -- Deposit sum into the account. do add (sum) end withdraw (sum : INTEGER) -- Withdraw sum from the account. do add (– sum) end may_withdraw (sum : INTEGER): BOOLEAN -- Is it permitted to withdraw sum from the account? do Result := (balance - sum >= Minimum_balance) end end

111 110 Introducing contracts class ACCOUNT create make feature {NONE } -- Initialization make (initial_amount: INTEGER) -- Set up account with initial_amount. require large_enough: initial_amount >= Minimum_balance do balance := initial_amount ensure balance_set: balance = initial_amount end

112 111 Introducing contracts feature -- Access balance: INTEGER -- Balance Minimum_balance : INTEGER = 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

113 112 Introducing contracts feature -- Deposit and withdrawal operations deposit (sum : INTEGER) -- Deposit sum into the account. require not_too_small: sum >= 0 do add (sum) ensure increased: balance = old balance + sum end Precondition Postcondition

114 113 Introducing contracts withdraw (sum : INTEGER) -- Withdraw sum from the account. require not_too_small: sum >= 0 not_too_big: sum <= balance – Minimum_balance do add (–sum) -- i.e. balance := balance – sum ensure decreased: balance = old balance - sum end Value of balance, captured on entry to routine

115 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 BENEFITS withdraw

116 115 The imperative and the applicative do balance := balance - sum ensure balance = old balance - sum PRESCRIPTIVEDESCRIPTIVE How? Operational Implementation Command Instruction Imperative What? Denotational Specification Query Expression Applicative

117 116 Introducing contracts may_withdraw (sum : INTEGER ): BOOLEAN -- Is it permitted to withdraw sum from account? do Result := (balance - sum >= Minimum_balance) end invariant not_under_minimum: balance >= Minimum_balance end

118 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 (...)

119 118 The correctness of a class For every creation procedure cp : {Pre cp } do cp {INV and Post cp } For every exported routine r : {INV and Pre r } do r {INV and Post r } x. f (…) x. g (…) x. h (…) create x. make (…) S1 S2 S3 S4

120 119 Uniform Access balance = deposits. total – withdrawals. total (A1) list_of_deposits list_of_withdrawals (A2) list_of_deposits list_of_withdrawals balance 1000

121 120 What are contracts good for? Writing correct software (analysis, design, implementation, maintenance, reengineering) Documentation (the contract form of a class) Effective reuse Controlling inheritance Preserving the work of the best developers Quality assurance, testing, debugging (especially in connection with the use of libraries) Exception handling

122 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)

123 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 }

124 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

125 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 software A revolutionary form of quality assurance

126 125 Lists in EiffelBase Cursor item index count1 forthback finishstart after before Munich"

127 126 Trying to insert too far right Cursor (Already past last element!) count 1 after "Munich"

128 127 A command and its contract Precondition Postcondition

129 128 Moving the cursor forward Cursor index forth count1 afterbefore "Munich"

130 129 Two queries, and command forth

131 130 Where the cursor may go Valid cursor positions 0index1 after before "Munich" countcount + 1

132 131 From the invariant of class LIST Valid cursor positions

133 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

134 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

135 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

136 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?)

137 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.

138 137 Uses of the contract &interface forms Documentation, manuals Design Communication between developers Communication between developers and managers

139 138 Contracts and inheritance Issues: what happens, under inheritance, to Class invariants? Routine preconditions and postconditions?

140 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.

141 140 Contracts and inheritance require ensure r require ensure a1 : A a1. r (…) … Correct call in C: if a1. then a1. r (...) -- Here a1. holds end r ++ CADB Client Inheritance ++ Redefinition

142 141 Assertion redeclaration rule When redeclaring a routine, we may only: Keep or weaken the precondition Keep or strengthen the postcondition

143 142 A simple language rule does the trick! Redefined version may have nothing (assertions kept by default), or require else new_pre ensure then new_post Resulting assertions are: original_precondition or new_pre original_postcondition and new_post Assertion redeclaration rule in Eiffel

144 143 Contracts as a management tool High-level view of modules for the manager: Follow whats going on without reading the code Enforce strict rules of cooperation between units of the system Control outsourcing

145 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.

146 145 Genericity and inheritance LIST_OF_ CARS SET_OF_ CARS LINKED_LIST_ OF_CARS LIST_OF_ CITIES LIST_OF_ PERSONS Abstraction Specialization Type parameterization Genericity Inheritance

147 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

148 147 An inheritance hierarchy center * display * rotate * perimeter * perimeter + perimeter ++ diagonal... perimeter ++ side2 * deferred + effective ++ redefine d perimeter ++ side1 CLOSED_ FIGURE OPEN_ FIGURE FIGURE SEGMENTPOLYLINETRIANGLEPOLYGONELLIPSE RECTANGLE SQUARECIRCLE side * * *

149 148 Redefinition 1: polygons class POLYGON inherit CLOSED_FIGURE create make feature vertex : ARRAY [POINT] vertex_count : INTEGER perimeter : REAL -- Perimeter length do from... until... loop Result := Result + vertex [i ]. distance (vertex [i + 1])... end end invariant vertex_count >= 3 vertex_count = vertex.count end vertex [i ] vertex [i + 1]

150 149 Redefinition 2: rectangles class RECTANGLE inherit POLYGON redefine perimeter end create make feature diagonal, side1, side2 : REAL perimeter : REAL -- Perimeter length do Result := 2 (side1 + side2) end invariant vertex_count = 4 end side1 side2 diagonal

151 150 Inheritance, typing &polymorphism (POLYGON ) (RECTANGLE ) p r Assume: p : POLYGON ; r : RECTANGLE ; t : TRIANGLE ; x : REAL Permitted: x := p. perimeter x := r. perimeter x := r. diagonal p := r NOT permitted: x := p. diagonal -- Even just after p := r ! r := p

152 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.

153 152 Dynamic binding What is the effect of this (assuming some_test true)? if some_test then p := r else p := 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

154 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.

155 154 Without dynamic binding! display (f : FIGURE ) do if f is a CIRCLE then... elseif f is a POLYGON then... end and similarly for all other routines! Tedious; must be changed whenever theres a new figure type

156 155 With inheritance &associated techniques f : FIGURE c : CIRCLE p : 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:

157 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 Genericity Inheritance

158 157 Genericity Unconstrained LIST [G] e.g. LIST [INTEGER], LIST [PERSON] Constrained HASH_TABLE [G > HASHABLE ] VECTOR [G > NUMERIC ]

159 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 : PERSON cities : LIST... people : LIST people. extend ( ) cities. extend ( ) c := cities. last c. some_city_operation What if wrong? p c

160 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

161 160 Using generic derivations cities : LIST [CITY ] people : LIST [PERSON] c : CITY p : 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) STATIC TYPING The compiler will reject: people. extend (c) cities. extend (p)

162 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.

163 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.)

164 163 Genericity + inheritance 1: Constrained genericity class VECTOR [G ] feature plus alias "+" (other : VECTOR [G]): VECTOR [G] -- Sum of current vector and other require lower = other. lower upper = other. upper local a, b, c: G do... See next... end... Other features... end

165 164 Adding two vectors + =uvw 1 2

166 165 Constrained genericity Body of plus alias "+": create Result. make (lower, upper) from i := lower until i > upper loop a := item (i) b := other. item (i) c := a + b-- Requires + operation on G! Result. put (c, i) i := i + 1 end

167 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.

168 167 Improving the solution Make VECTOR itself a descendant of NUMERIC, effecting the corresponding features: class VECTOR [G –> NUMERIC ] inherit NUMERIC feature... Rest as before, including infix "+"... end Then it is possible to define v : VECTOR [INTEGER ] vv : VECTOR [VECTOR [INTEGER ]] vvv : VECTOR [VECTOR [VECTOR [INTEGER ]]]

169 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

170 169 Genericity + inheritance 2: Polymorphic data structures figs : LIST [FIGURE ] p1, p2 : POLYGON c1, c2 : CIRCLE e : ELLIPSE (POLYGON) (CIRCLE) (POLYGON) (CIRCLE) (ELLIPSE) class LIST [G ] feature extend (v : G) do … end last : G … end figs. extend (p1 ) ; figs. extend (c1 ) ; figs. extend (c2 ) figs. extend (e ) ; figs. extend (p2 )

171 170 Combining abstractions Given the classes TRAIN_CAR, RESTAURANT how would you implement a DINER ?

172 171 Examples of multiple inheritance Combining separate abstractions: Restaurant, train car Calculator, watch Plane, asset Home, vehicle Tram, bus

173 172 Composite figures

174 173 Multiple inheritance: Composite figures A composite figure Simple figures

175 174 Defining the notion of composite figure COMPOSITE_ FIGURE center display hide rotate move … count put remove … FIGURE LIST [FIGURE ]

176 175 In the overall structure COMPOSITE_ FIGURE FIGURE LIST [FIGURE ] OPEN_ FIGURE CLOSED_ FIGURE SEGMENTPOLYLINEPOLYGON ELLIPSE RECTANGLE SQUARE CIRCLE TRIANGLE perimeter + perimeter* perimeter ++ diagonal perimeter ++ perimeter +

177 176 A composite figure as a list Cursor item forth after

178 177 Composite figures class COMPOSITE_FIGURE inherit FIGURE LIST [FIGURE] feature display -- Display each constituent figure in turn. do from start until after loop item. display forth end end... Similarly for move, rotate etc.... end Requires dynamic binding

179 178 Multiple inheritance: Combining abstractions COMPARABLE NUMERIC STRING COMPLEX INTEGER REAL, >=, … +, –,, / … (total order relation) (commutative ring)

180 179 Renaming Graphical features: height, width, change_height, change_width, xpos, ypos, move... Hierarchical features: superwindow, subwindows, change_subwindow, add_subwindow... class WINDOW inherit RECTANGLE TREE [WINDOW] rename parent as superwindow, children as subwindows, add_child as add_subwindow … end feature... end BUT: see style rules about uniformity of feature names

181 Some new developments

182 181 Some recent developments Void safety Automatic testing Concurrency

183 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?

184 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: 1 st semester teachability)

185 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

186 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

187 186 Caveat I am mostly talking about: Functional testing Unit testing

188 187 What is testing about? To test a software system is to try to make it fail Testing is none of: Ensuring software quality Assessing software quality Debugging (Terminology: failure, fault, mistake) Fiodor Chaliapine as Mephistopheles Ich bin der Geist, der stets verneint Goethe, Faust, Act I

189 188 1.To test a program is to try to make it fail 2.Tests are no substitute for specifications 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 contracts 5.A test suite must include both manual and automated cases 6.Dont believe your testing insights: evaluate any testing strategy through objective criteria 7.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

190 189 Automated testing What can be automated: Test suite execution Resilience Regression testing Test case generation Test result verification (oracles) Test case minimization

191 190 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.

192 191 AutoTest: automatic test framework Input: set of classes + testing time Generates instances, calls routines with automatically selected 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 Ciupa Andreas Leitner (SOFSEM 2007 etc.)

193 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, )... create {ACCOUNT} v3.make (v2) v3. deposit (15) v3. deposit (100) v3. deposit (-8901)... class ACCOUNT create make feature make (n : STRING) require n /= Void do name := n balance := 0 ensure name = n balance = 0 end name : STRING balance : INTEGER deposit (v : INTEGER) do balance := balance + v ensure balance = old balance + v end invariant name /= Void balance >= 0 end

194 193 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)

195 194 Random testing: example bug found * SET * + SET1 + SET2 + + Test: s1, s2 : SET s2 s1 *: Deferred + : Effective Bernd Schoeller

196 195 Some AutoTest results (random strategy) Library TotalFailed TotalFailed EiffelBase (Sep 2005) 40,0003%20006% Gobo Math 15001%1406% TESTS ROUTINES

197 196 Testing results and strategy Smart ideas not always better Dont believe your intuition Measure 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

198 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 routines precondition Infinite loop

199 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% implementation User reports: 36% specification, 64% implementation I.Ciupa, A. Leitner, M.Oriol, A. Pretschner (submitted)

200 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)

201 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)

202 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

203 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

204 20 3 Specified but unimplemented routine

205 204 Running the system and entering input (erroneous) 20

206 20 5 Postcondition violated The violated clause: balance > old balance Error caught at run time as contract violation

207 20 6 This has become a test case 206

208 20 7 Correcting and recompiling

209 20 8 One fault corrected, the other not

210 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

211 210 Concurrency: the SCOOP model General-purpose Multi-threading, Web services, distribution, multiprogramming... Simplifies concurrent programming Based on Design by Contract ideas

212 211 Summary Bring every one of your development days to the level of your best days

213 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, 1887 From 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


Download ppt "Eiffel in Depth Bertrand Meyer With material by Emmanuel Stapf (Eiffel Software) & members of the ETH Chair of Software Engineering Chair of Software."

Similar presentations


Ads by Google