So why the big fuss about Design by Contract? Bertrand Meyer Software Architecture, March 2008
Verification: the vision “Guardian angel” approach: environment checks your software as you write it “Squiggly red underscore” of Microsoft Word Combination of techniques: Automatic testing through AutoTest Manual tests Regression tests CDD Static analysis Proofs All of this integrated into EiffelStudio 2
Design by Contract A discipline of analysis, design, implementation, management 3
Design by Contract Together with the implementation (“ how ”) of each software element, describe “ what ” it is supposed to do: its contract Three basic questions about every software element: What does it assume? Precondition What does it guarantee? Postcondition What does it maintain? Invariant 4
With and without contracts Karine Arnout (IEEE Computer) .Net collections library EiffelBase 5
Applications of Design by Contract Getting the software right Analysis Design Implementation Debugging Testing Management Maintenance Documentation 6
The metaphor: contracts in business A contract: Binds two parties (or more): supplier, client Is explicit (written) Specifies mutual obligations and benefits Usually maps obligation for one of the parties into benefit for the other, and conversely Has no hidden clauses: obligations are those specified Often relies, implicitly or explicitly, on general rules applicable to all contracts: laws, regulations, standard practices 7
A human contract OBLIGATIONS BENEFITS deliver (Satisfy precondition:) (From postcondition:) Client Bring package before 4 Get package delivered by p.m.; pay fee. 10 a.m. next day. (From precondition:) (Satisfy postcondition:) Supplier Not required to do Deliver package by 10 anything if package a.m. next day. delivered after 4 p.m., or fee not paid. 8
A 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 9
Correctness in software Correctness is a relative notion: consistency of implementation vis-à-vis specification. Basic notation: ( P , Q : assertions, i.e. properties of the state of the computation. A : instructions). { P } A { Q } “Hoare triple” What this means (total correctness): Any execution of A started in a state satisfying P will terminate in a state satisfying Q . 10
Hoare triples: a simple example {n > 5} n := n + 9 {n > 13} Most interesting properties: Strongest postcondition (from given precondition). Weakest precondition (from given postcondition). “ P is stronger than or equal to Q ” means: P implies Q QUIZ: What is the strongest possible assertion? The weakest? 11
A class without contracts class ACCOUNT feature -- Access balance : INTEGER -- Balance Secret Minimum_balance : INTEGER = 1000 -- Minimum balance features feature { NONE } -- Deposit and withdrawal add ( sum : INTEGER ) -- Add sum to the balance . do balance := balance + sum end 12
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 13
Introducing contracts class ACCOUNT create make feature { NONE } -- Initialization make ( initial_amount : INTEGER ) -- Set up account with initial_amount require do balance := initial_amount ensure end 14
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 15
Introducing contracts feature -- Deposit and withdrawal operations deposit ( sum : INTEGER ) -- Deposit sum into the account. Precondition require not_too_small: sum >= 0 do Postcondition add ( sum ) ensure increased: balance = old balance + sum end 16
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 17
The contract OBLIGATIONS BENEFITS withdraw (Satisfy precondition:) (From postcondition:) Client Make sure sum is neither Get account updated with too small nor too big sum withdrawn (From precondition:) (Satisfy postcondition:) Supplier Simpler processing: may Update account for assume sum is within withdrawal of sum allowable bounds 18
The imperative and the applicative do ensure balance := balance - sum balance = old balance - sum PRESCRIPTIVE DESCRIPTIVE How? What? Operational Denotational Implementation Specification Command Query Dynamic Static 19
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 20
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 (...) 21
The correctness of a class create x . make (…) S1 x . f (…) For every creation procedure cp : S2 {Pre cp } do cp { INV and Post cp } x . g (…) S3 For every exported routine r : x . h (…) S4 { INV and Pre r } do r { INV and Post r } 22
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 23
Object-oriented (requirements) analysis Same benefits as O-O programming, in particular extendibility and reusability Direct modeling of the problem domain Seamlessness and reversibility with the continuation of the project (design, implementation, maintenance) 24
Contracts for analysis Specify semantics, but abstractly! Basic dilemma of requirements: Committing too early to an implementation Overspecification Missing parts of the problem Underspecification 25
Television station example Source: OOSC 26
Schedules note set_air_time ( t : DATE ) description : -- Assign schedule to “ 24-hour TV schedules ” -- be broadcast at time t . deferred class SCHEDULE feature require t . in_future segments : LIST [ SEGMENT ] -- Successive segments deferred deferred ensure end air_time = t end air_time : DATE is -- 24-hour period print -- for this schedule -- Produce paper version. deferred deferred end end end 27
Segment note sponsor : COMPANY deferred end -- Segment’s principal sponsor description : “Fragments of a schedule " deferred class SEGMENT feature rating : INTEGER deferred end schedule : SCHEDULE deferred end -- Segment’s rating (for -- Schedule to which segment belongs -- children’s viewing etc.) index : INTEGER deferred end -- Position of segment in … Commands such as change_next , -- its schedule set_sponsor , set_rating omitted … starting_time , ending_time : INTEGER deferred end Minimum_duration : INTEGER = 30 -- Beginning and end of -- Minimum length of segments, -- scheduled air time -- in seconds next: SEGMENT deferred end -- Segment to be played Max_interval : INTEGER = 2 -- next, if any -- Maximum time between two -- successive segments, in seconds 28
Segment (continued) invariant in_list: ( 1 <= index ) and ( index <= schedule . segments . count ) in_schedule: schedule . segments . item ( index ) = Current next_in_list: ( next /= Void ) implies ( schedule . segments . item ( index + 1) = next ) no_next_iff_last: ( next = Void ) = ( index = schedule . segments . count ) non_negative_rating: rating >= 0 positive _ times: ( starting_time > 0 ) and ( ending_time > 0 ) sufficient_duration: ending_time – starting_time >= Minimum_duration decent_interval : ( next . starting_time ) - ending_time <= Max_interval end 29
Recommend
More recommend