1 introduction to: design by contract fall 2005 oopd john anthony
Post on 21-Dec-2015
217 views
TRANSCRIPT
1
Introduction to:Introduction to:Design by Design by Contract Contract
Fall 2005 OOPDFall 2005 OOPDJohn AnthonyJohn Anthony
2 John J. AnthonyObject Oriented Programming & Design
Design QuestionDesign Question
You have created a Car class with an operation You have created a Car class with an operation named named addEnging(e : Engine)addEnging(e : Engine).. The rule is that you The rule is that you can only add one engine to the car (adding two is can only add one engine to the car (adding two is invalid). How would you implement this rule?invalid). How would you implement this rule?
• return a boolean value indicating the success of adding an engine
• allow the addEngine to be called and then throw an exception if an engine already exists.
• ask the client to check the state of the Car to determine if it already has an engine
• 1 AND 3
3 John J. AnthonyObject Oriented Programming & Design
What is a ContractWhat is a Contract
An entity which describes the An entity which describes the obligations between 2 or more parties obligations between 2 or more parties which, when fulfilled, provides certain which, when fulfilled, provides certain rights to the parties.rights to the parties.
4 John J. AnthonyObject Oriented Programming & Design
More SpecificallyMore SpecificallyAssertion Assertion
TypeTypeObligationObligation RightRight
PreconditioPreconditionn
ClientClient
Clients must fulfill the Clients must fulfill the precondition as specified precondition as specified by a supplier.by a supplier.
ClientClient
If obligation met, client has If obligation met, client has the right to expect the the right to expect the postconditions are truepostconditions are true
PostconditiPostconditionon
SupplierSupplier
Supplier must provide Supplier must provide certain guarantees when certain guarantees when service is invokedservice is invoked
SupplierSupplier
Has the right to expect the Has the right to expect the preconditions are true.preconditions are true.
Contracts are “specs ‘n’ checks.”
5 John J. AnthonyObject Oriented Programming & Design
Courier ExampleCourier Example
ClientClient SupplierSupplier
ObligationObligation PreconditionPrecondition
Don’t ask for delivery of Don’t ask for delivery of packages over 5 lbs in packages over 5 lbs in weightweight
PostconditionPostcondition
Deliver package within 3 Deliver package within 3 working hoursworking hours
BenefitBenefit PostconditionPostcondition
Get package delivered Get package delivered within 3 working hours.within 3 working hours.
PreconditionPrecondition
Don’t have to cope with Don’t have to cope with packages over 5 lbs in packages over 5 lbs in weight.weight.
6 John J. AnthonyObject Oriented Programming & Design
ExampleExample
count: INTEGER
-- the number of customers the managing object manages
id_active(an_id : CUSTOMER_ID) : BOOLEAN
-- is there a customer with ‘an_id’
add(a_customer : BASIC_CUSTOMER_DETAILS)
-- add ‘a_customer’ to the set of customers being managed
name_for(an_id : CUSTOMER_ID): STRING
--what is the name of the customer with ‘an_id’
set_name(an_id : CUSTOMER_ID, a_name : STRING)
--set the name of the customer with ‘an_id’ to ‘a_name’
CUSTOMER_MANAGER
7 John J. AnthonyObject Oriented Programming & Design
ExampleExample
id : CUSTOMER_ID
name : STRING
address : STRING
date_of_birth : DATE
BASIC_CUSTOMER_DETAILS
8 John J. AnthonyObject Oriented Programming & Design
ExampleExample
BASIC_CUSTOMER_DETAILS
CUSTOMER_MANAGER
9 John J. AnthonyObject Oriented Programming & Design
Some Design QuestionsSome Design Questions How do I make an id active? By adding a How do I make an id active? By adding a
customer with that id?customer with that id?
If I add a customer whose details match an If I add a customer whose details match an existing customer’s basic details, what happens?existing customer’s basic details, what happens?
What do I get if I ask for the name of a customer What do I get if I ask for the name of a customer whose id is not active?whose id is not active?
What happens if I set the name for a customer What happens if I set the name for a customer whose id is not active?whose id is not active?
10 John J. AnthonyObject Oriented Programming & Design
Adding a New CustomerAdding a New Customer
add(a_customer : BASIC_CUSTOMER_DETAILS)add(a_customer : BASIC_CUSTOMER_DETAILS)
--add ‘a_customer’ to the set of customers--add ‘a_customer’ to the set of customers
requirerequire
id_not_already_active: id_not_already_active: notnot id_active(a_customer.id) id_active(a_customer.id)
…………....
ensureensure
count_increased : count = count_increased : count = oldold count + 1 count + 1
customer_id_now_active : id_active(a_customer.id)customer_id_now_active : id_active(a_customer.id)
precondition: responsibility of client to ensure
expression is true
postcondition: responsibility of
supplier to ensure expressions are true
after feature execution
assertion: an expression that must evaluate to
true
11 John J. AnthonyObject Oriented Programming & Design
Some Answers…Some Answers… How do I make an id active? By adding a customer with How do I make an id active? By adding a customer with
that id?that id? YesYes
If I add a customer whose details match an existing If I add a customer whose details match an existing customer’s basic details, what happens?customer’s basic details, what happens? Not allowed to add a customer whose id equals the id of a Not allowed to add a customer whose id equals the id of a
customer already owned by the manager. There are no other customer already owned by the manager. There are no other constrains on other features such as name, address, DOB, etc.constrains on other features such as name, address, DOB, etc.
12 John J. AnthonyObject Oriented Programming & Design
Setting the Name of Setting the Name of CustomerCustomer
set_name(an_id : CUSTOMER_ID, a_name : STRING)set_name(an_id : CUSTOMER_ID, a_name : STRING)--set the name of the customer with ‘an_id’ to ‘a_name’--set the name of the customer with ‘an_id’ to ‘a_name’
requirerequireid_active: id_active(an_id)id_active: id_active(an_id)
…………....
ensureensurename_set: name_for(an_id).is_equal(a_name)name_set: name_for(an_id).is_equal(a_name)
13 John J. AnthonyObject Oriented Programming & Design
Asking for the Name of a Asking for the Name of a CustomerCustomer
name_for(an_id : CUSTOMER_ID : STRINGname_for(an_id : CUSTOMER_ID : STRING--the name of the customer with ‘an_id’--the name of the customer with ‘an_id’
requirerequireid_active: id_active(an_id)id_active: id_active(an_id)
…………....
14 John J. AnthonyObject Oriented Programming & Design
More Answers…More Answers… What do I get if I ask for the name of a customer What do I get if I ask for the name of a customer
whose id is not active?whose id is not active? It is illegal to ask for the name of a customer whose id It is illegal to ask for the name of a customer whose id
is not active.is not active.
What happens if I set the name for a customer What happens if I set the name for a customer whose id is not active?whose id is not active? It is illegal to attempt to set the name of a customer It is illegal to attempt to set the name of a customer
whose id is not active.whose id is not active.
15 John J. AnthonyObject Oriented Programming & Design
Class InvariantsClass Invariants
A condition that always resolves to True A condition that always resolves to True ((more precisely, it is true whenever you more precisely, it is true whenever you can call a feature on the componentcan call a feature on the component).).
invariantinvariantcount_never_negative: count >= 0count_never_negative: count >= 0
16 John J. AnthonyObject Oriented Programming & Design
Contract ViolationsContract Violations
What would happen if we (attempt) to add What would happen if we (attempt) to add a customer whose id is already active?a customer whose id is already active?
Stopped in Stopped in objectobject [0xE96978][0xE96978]ClassClass: CUSTOMER_MANAGER: CUSTOMER_MANAGERFeatureFeature: add: addProblemProblem: Precondition violated: Precondition violatedTagTag: id_not_already_active: id_not_already_activeArgumentsArguments: a_customer: BASIC_CUSTOMER_DETAILS [OXe9697C]: a_customer: BASIC_CUSTOMER_DETAILS [OXe9697C]Call Stack:Call Stack:
CUSTOMER_MANAGER addCUSTOMER_MANAGER addwas called by CUSTOMER_MANAGER_UIF change_customerwas called by CUSTOMER_MANAGER_UIF change_customer
17 John J. AnthonyObject Oriented Programming & Design
A Simple StackA Simple Stack
count: INTEGER
Is_empty : BOOLEAN
initialize
push (i : INTEGER)
pop(out I : INTEGER)
STACK
18 John J. AnthonyObject Oriented Programming & Design
Principle 1Principle 1
Separate commands from queriesSeparate commands from queries
Queries return a result but do not Queries return a result but do not change the visible properties of the change the visible properties of the object. Commands might change the object. Commands might change the object but do not return a result.object but do not return a result.
19 John J. AnthonyObject Oriented Programming & Design
Principle 1Principle 1Let’s write the contract for the push command…Let’s write the contract for the push command…
push (I : INTEGER)push (I : INTEGER)--push ‘i onto the top of the Stack--push ‘i onto the top of the Stack……..
ensureensuretop_is_i : i = ?????top_is_i : i = ????? count: INTEGER
Is_empty : BOOLEAN
initialize
push (i : INTEGER)
pop() : INTEGER
STACK
push (I : INTEGER)push (I : INTEGER)--push ‘i onto the top of the Stack--push ‘i onto the top of the Stack……..
ensureensuretop_is_i : i = poptop_is_i : i = pop
20 John J. AnthonyObject Oriented Programming & Design
push (I : INTEGER)push (I : INTEGER)--push ‘i onto the top of the Stack--push ‘i onto the top of the Stack……..
ensureensuretop_is_i : i = poptop_is_i : i = pop
count: INTEGER
Is_empty : BOOLEAN
initialize
push (i : INTEGER)
top : INTEGER
delete
STACK
push (I : INTEGER)push (I : INTEGER)--push ‘i onto the top of the Stack--push ‘i onto the top of the Stack……..
ensureensuretop_is_i : top = itop_is_i : top = i
Principle 1Principle 1
21 John J. AnthonyObject Oriented Programming & Design
Commands vs. QueriesCommands vs. Queries
features
routines
procedures
attributes
functions
creation other
QU
ERIES
COMMANDS
22 John J. AnthonyObject Oriented Programming & Design
The Revised StackThe Revised Stack
count: INTEGER
Is_empty : BOOLEAN
initialize
push (i : INTEGER)
top : INTEGER
delete
STACK
<<Queries>>
count: INTEGER
--the number of items on the stack
item : INTEGER
--the top item
Is_empty : BOOLEAN
--is the stack empty?
<<Creation Commands>>
Initialize
<Other Commands>>
put (i : INTEGER)
--put ‘I’ onto the top of stack
remove
--remove the top item
STACK
Eiffel Naming Conventi
ons
23 John J. AnthonyObject Oriented Programming & Design
Principle 2Principle 2
Separate basic queries from Separate basic queries from derived queriesderived queries
Derived queries can be specified in Derived queries can be specified in terms of queries.terms of queries.
24 John J. AnthonyObject Oriented Programming & Design
Principle 3Principle 3
For each derived query, write a For each derived query, write a postcondition that specifies what postcondition that specifies what result will be returned in terms of result will be returned in terms of one or more basic queries.one or more basic queries.
Then, if we know the values of the Then, if we know the values of the basic queries, we also know the values basic queries, we also know the values of the derived queries.of the derived queries.
25 John J. AnthonyObject Oriented Programming & Design
Principle 2 & 3Principle 2 & 3
Is_empty : BOOLEANIs_empty : BOOLEAN--does the stack contain no items--does the stack contain no items……..
ensureensureconsistent_with_count: Result = (count = 0)consistent_with_count: Result = (count = 0)
The assertion is defined in terms of the count query.
if(count > 0) Result := falseelse Result :=true
Principle 2Since is_empty is derived from count
Principle 3Since postcondition is defined in terms of count
26 John J. AnthonyObject Oriented Programming & Design
Revised StackRevised Stack
<< Basic Queries>>
count: INTEGER
--the number of items on the stack
item : INTEGER
--the top item
<<Derived Queries>>
Is_empty : BOOLEAN
--is the stack empty?
<<Creation Commands>>
Initialize
<Other Commands>>
put (i : INTEGER)
--put ‘I’ onto the top of stack
remove
--remove the top item
STACK
27 John J. AnthonyObject Oriented Programming & Design
Principle 4Principle 4
For each command, write a For each command, write a postcondition that specifies the postcondition that specifies the value of every basic query.value of every basic query.
Taken together with the principle of Taken together with the principle of defining derived queries in terms of defining derived queries in terms of basic queries, this means that we basic queries, this means that we know the total visible effect of each know the total visible effect of each command.command.
28 John J. AnthonyObject Oriented Programming & Design
Principle 4Principle 4
put (I : INTEGER)put (I : INTEGER)--push ‘I’ onto the top of the stack--push ‘I’ onto the top of the stack……..
ensureensurecount_increased: count = old count + 1count_increased: count = old count + 1g_on_top: item = ig_on_top: item = i
Count increased
by 1
Top of stack equal to i
29 John J. AnthonyObject Oriented Programming & Design
Principle 4Principle 4
initializeinitialize--initialize the stack to be empty--initialize the stack to be empty……..
ensureensurestack_contains_zero_items: count = 0stack_contains_zero_items: count = 0
count set to 0
What about the second basic query; item????
30 John J. AnthonyObject Oriented Programming & Design
Principle 4Principle 4
itemitem--return the top item of the stack--return the top item of the stack
requirerequirestack_not_empty: count > 0stack_not_empty: count > 0
Count must be greater than 0 in order to call
item
Now, our contract on initialize ensures that:• the value of count is zero• the top item has no value
31 John J. AnthonyObject Oriented Programming & Design
Principle 4Principle 4
removeremove--delete the top item--delete the top item
requirerequirestack_not_empty: count > 0stack_not_empty: count > 0
ensureensurecount_decreased: count = old count - 1count_decreased: count = old count - 1top_item_removed: Result = old itemtop_item_removed: Result = old item
Ensures that we do not try to
remove an item from an empty
stack.
32 John J. AnthonyObject Oriented Programming & Design
Principle 5Principle 5
For every query and command, For every query and command, decide on a suitable precondition.decide on a suitable precondition.
Preconditions constrain when clients Preconditions constrain when clients may call the queries and commands.may call the queries and commands.
33 John J. AnthonyObject Oriented Programming & Design
Principle 6Principle 6
Write invariants to define Write invariants to define unchanging properties of objects.unchanging properties of objects.
Concentrate on properties that help Concentrate on properties that help the reader build an appropriate the reader build an appropriate conceptual model of the abstraction conceptual model of the abstraction that the class embodies.that the class embodies.
34 John J. AnthonyObject Oriented Programming & Design
Principle 6Principle 6
invariantinvariantcount_never_negative: count > 0count_never_negative: count > 0
35 John J. AnthonyObject Oriented Programming & Design
Contracts and Contracts and InheritanceInheritance
How are contracts inherited from How are contracts inherited from parent classes.parent classes.
How can contracts be redefined?How can contracts be redefined?
How can we construct subclasses How can we construct subclasses that respect the parent’s contract?that respect the parent’s contract?
36 John J. AnthonyObject Oriented Programming & Design
ClientClient SupplierSupplier
ObligationObligation PreconditionPrecondition
Don’t ask for delivery of Don’t ask for delivery of packages over 5 lbs in packages over 5 lbs in weightweight
PostconditionPostcondition
Deliver package within 3 Deliver package within 3 working hoursworking hours
BenefitBenefit PostconditionPostcondition
Get package delivered Get package delivered within 3 working hours.within 3 working hours.
PreconditionPrecondition
Don’t have to cope with Don’t have to cope with packages over 5 lbs in packages over 5 lbs in weight.weight.
Remember….
Back to Courier ExampleBack to Courier Example
37 John J. AnthonyObject Oriented Programming & Design
Courier ClassCourier Class
class COURIERclass COURIERfeaturefeature
deliver (p : PACKAGE, d : DESTINATION)deliver (p : PACKAGE, d : DESTINATION)--deliver package to destination--deliver package to destination
requirerequire--weight of package p does not exceed --weight of package p does not exceed
5 lbs.5 lbs.
…………..
ensureensure--package delivered within 3 working --package delivered within 3 working
hourshours
…………..
endend
38 John J. AnthonyObject Oriented Programming & Design
Remember Remember Polymorphism?Polymorphism?
Courier
Different_Courier
Client
a_courier : Different_Courier
<<instance of>>
a_client : Client
1. A client is given access to a courier object
2. The client thinks it is using a deliver service from
a regular kind of courier. 3. But the service is actually provided by a different
kind of courier….will the service
be acceptable to the client?
deliver(…)
deliver(…)
39 John J. AnthonyObject Oriented Programming & Design
Consider New Consider New PreconditionsPreconditions
weight of package must not exceed 8 lbsweight of package must not exceed 8 lbs weight of package must not exceed 3 lbsweight of package must not exceed 3 lbs weight of package must not exceed 2 lbsweight of package must not exceed 2 lbs
Which precondition(s) are acceptable?
40 John J. AnthonyObject Oriented Programming & Design
Consider New Consider New PostconditionsPostconditions
package will be delivered within 2 hourspackage will be delivered within 2 hours package will be delivered in 3 working hourspackage will be delivered in 3 working hours package will be delivered in 5 working hourspackage will be delivered in 5 working hours
Which postcondition(s) are acceptable?
41 John J. AnthonyObject Oriented Programming & Design
Different_CourierDifferent_Courier
class DIFFERENT_COURIERclass DIFFERENT_COURIERfeaturefeature
deliver (p : PACKAGE, d : DESTINATION)deliver (p : PACKAGE, d : DESTINATION)--deliver package to destination--deliver package to destination
require elserequire else--weight of package p does not exceed --weight of package p does not exceed
8 lbs.8 lbs.
…………..
ensure thenensure then--package delivered within 2 working --package delivered within 2 working
hourshours
…………..
endend
42 John J. AnthonyObject Oriented Programming & Design
Complete PreconditionComplete Preconditiondeliver (p : PACKAGE, d : DESTINATION)deliver (p : PACKAGE, d : DESTINATION)
--deliver package to destination--deliver package to destinationrequirerequire
--weight of package p does not exceed 5 --weight of package p does not exceed 5 lbs.lbs.
require elserequire else--weight of package p does not exceed 8 --weight of package p does not exceed 8
lbs.lbs.
Weight of package does not exceed 5 lbs.Weight of package does not exceed 5 lbs.
or elseor else
Weight of package does not exceed 8 lbs.Weight of package does not exceed 8 lbs.
43 John J. AnthonyObject Oriented Programming & Design
Complete PostconditionComplete Postconditiondeliver (p : PACKAGE, d : DESTINATION)deliver (p : PACKAGE, d : DESTINATION)
--deliver package to destination--deliver package to destinationensureensure
--package delivered within 3 working --package delivered within 3 working hourshours
ensure thenensure then-- package delivered within 2 working -- package delivered within 2 working
hourshours
Package delivered within 3 working hoursPackage delivered within 3 working hours
and thenand then
Package delivered within 2 working hoursPackage delivered within 2 working hours
44 John J. AnthonyObject Oriented Programming & Design
Benefits of Design by Benefits of Design by ContractContract
Benefits include:Benefits include: Achieving better designsAchieving better designs Improving reliabilityImproving reliability Getting better documentationGetting better documentation
45 John J. AnthonyObject Oriented Programming & Design
Better DesignsBetter Designs More Systematic DesignsMore Systematic Designs
Designers are encouraged to think about such as matters as Designers are encouraged to think about such as matters as preconditions and postconditions resulting in concepts being preconditions and postconditions resulting in concepts being more explicit.more explicit.
Clearer DesignsClearer Designs The obligations and benefits are shared between the client and The obligations and benefits are shared between the client and
the suppler and are clearly stated.the suppler and are clearly stated.
Simpler DesignsSimpler Designs Limitations on the use of a routine are clearly expressed in its Limitations on the use of a routine are clearly expressed in its
precondition, and the consequences of calling it illegally are precondition, and the consequences of calling it illegally are clear.clear.
Systematic Use of ExceptionsSystematic Use of Exceptions Exceptions are thrown when a routine is used illegally (false Exceptions are thrown when a routine is used illegally (false
precondition) or when a routine fails to fulfill its contract (false precondition) or when a routine fails to fulfill its contract (false postcondition)…and nothing in betweenpostcondition)…and nothing in between
46 John J. AnthonyObject Oriented Programming & Design
Improved ReliabilityImproved Reliability Better Understood and Hence More Reliable Better Understood and Hence More Reliable
CodeCode Separates the Separates the contract contract code from the code from the implementation implementation
code. Requires the implementer to think about the code. Requires the implementer to think about the “specification” from two perspectives.“specification” from two perspectives.
Better Tested and Hence More Reliable CodeBetter Tested and Hence More Reliable Code Assertions are checked at runtime, thereby testing that Assertions are checked at runtime, thereby testing that
routines fulfill their stated contracts. (A formal routines fulfill their stated contracts. (A formal approach to test-driven development)approach to test-driven development)
47 John J. AnthonyObject Oriented Programming & Design
Better DocumentationBetter Documentation Clearer DocumentationClearer Documentation
Contracts form part of the public, or client, view of a Contracts form part of the public, or client, view of a class..class..
More Reliable DocumentationMore Reliable Documentation Assertions are checked at runtime, thereby testing that Assertions are checked at runtime, thereby testing that
the stated contracts are the stated contracts are consistentconsistent with what the with what the routines actually do.routines actually do.