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 1
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 2
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 3
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 features feature { NONE } -- Deposit and withdrawal add ( sum : INTEGER ) -- Add sum to the balance . do balance := balance + sum end 12 4
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 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 5
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:) Supplier (Satisfy postcondition:) Simpler processing: may Update account for assume sum is within withdrawal of sum allowable bounds 18 6
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 7
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 8
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 end deferred end end 27 9
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 Commercial set_primary ( p : PROGRAM ) note -- Attach commercial to p . description: " Advertising segment " require deferred class COMMERCIAL inherit program_exists: p /= Void SEGMENT rename same_schedule: p , schedule = schedule before: p . starting_time <= starting_time sponsor as advertiser end deferred feature ensure primary : PROGRAM deferred index_updated: primary_index = p . index -- Program to which this -- commercial is attached primary_updated: primary = p end primary_index : INTEGER deferred -- Index of primary invariant meaningful_primary_index: primary_index = primary . index primary_before: primary . starting_time <= starting_time acceptable_sponsor: advertizer . compatible ( primary . sponsor ) acceptable_rating: rating <= primary . rating end 30 10
Recommend
More recommend