49
3. Design by Contract

3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

  • View
    229

  • Download
    0

Embed Size (px)

Citation preview

Page 1: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

3. Design by Contract

Page 2: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

Design by Contract

© Oscar Nierstrasz

Design by Contract

2.2

Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall, 1997.

Page 3: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz 3

Roadmap

> Contracts> Stacks> Design by Contract> A Stack Abstraction> Assertions> Example: balancing parentheses

Safety Patterns

Page 4: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz 4

Roadmap

> Contracts> Stacks> Design by Contract> A Stack Abstraction> Assertions> Example: balancing parentheses

Safety Patterns

Page 5: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

Class Invariants

© Oscar Nierstrasz

Design by Contract

5

An invariant is a predicate that must hold at certain pointsin the execution of a program

A class invariant characterizes the valid states of instancesIt must hold:

1. after construction2. before and after every public method

Page 6: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.6

Contracts

A contract binds the client to pose valid requests, andbinds the provider to correctly provide the service.

Page 7: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.7

Contract violations

If either the client or the provider violates the contract, an exception is raised.

NB: The service does not need to implement any special logic to handle errors — it simply raises an exception!

Page 8: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.8

Exceptions, failures and defects

> An exception is the occurrence of an abnormal condition during the execution of a software element.

> A failure is the inability of a software element to satisfy its purpose.

> A defect (AKA “bug”) is the presence in the software of some element not satisfying its specification.

Page 9: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

Disciplined Exceptions

> There are only two reasonable ways to react to an exception:1. clean up the environment and report failure to the client

(“organized panic”)2. attempt to change the conditions that led to failure and retry

© Oscar Nierstrasz

Design by Contract

2.9

A failed assertion often indicates presence of a software defect, so “organized panic” is usually the best policy.

Page 10: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz 10

Roadmap

> Contracts> Stacks> Design by Contract> A Stack Abstraction> Assertions> Example: balancing parentheses

Safety Patterns

Page 11: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.11

Stacks

A Stack is a classical data abstraction with many applications in computer programming.Stacks support two mutating methods: push and pop.

Operation Stack isEmpty() size() top()

TRUE 0 (error)

push(6) FALSE 1 6

push(7) FALSE 2 7

push(3) FALSE 3 3

pop() FALSE 2 7

push(2) FALSE 3 2

pop() FALSE 2 7

6 7

6 7 3

6 7

6 7 2

6 7

6

Page 12: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.12

Stack pre- and postconditions

Stacks should respect the following contract:

service pre post

isEmpty() - no state change

size() - no state change

push(Object item) -not empty, size == old size + 1,top == item

top() not empty no state change

pop() not empty size == old size -1

Page 13: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

Stack invariant

> The only thing we can say about the Stack class invariant is that the size is always ≥ 0— we don’t know anything yet about its state!

© Oscar Nierstrasz

Design by Contract

13

Page 14: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz 14

Roadmap

> Contracts> Stacks> Design by Contract> A Stack Abstraction> Assertions> Example: balancing parentheses

Safety Patterns

Page 15: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

Design by Contract

© Oscar Nierstrasz

Design by Contract

2.15

“If you promise to call S with the precondition satisfied, then I, in return, promise to deliver a final state in which the post-condition is satisfied.”

Consequence:—if the precondition does not hold, the object is not required to

provide anything! (in practice, an exception is raised)

When you design a class, each service S provided must specify a clear contract.

Page 16: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.16

In other words …

Design by Contract = Don’t accept anybody else’s garbage!

Page 17: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.17

Pre- and Post-conditions

The pre-condition binds clients: — it defines what the data abstraction requires for a call to the

operation to be legitimate— it may involve initial state and arguments— example: stack is not empty

The post-condition, in return, binds the provider: — it defines the conditions that the data abstraction ensures on

return— it may only involve the initial and final states, the arguments and

the result— example: size = old size + 1

Page 18: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.18

Benefits and Obligations

A contract provides benefits and obligations for both clients and providers:

Obligations Benefits

Client Only call pop() on a non-empty stack!

Stack size decreases by 1.Top element is removed.

ProviderDecrement the size. Remove the top element.

No need to handle case when stack is empty!

Page 19: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz 19

Roadmap

> Contracts> Stacks> Design by Contract> A Stack Abstraction> Assertions> Example: balancing parentheses

Safety Patterns

Page 20: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.20

StackInterface

Interfaces let us abstract from concrete implementations:

How can clients accept multiple implementations of a data abstraction?

Make them depend only on an interface or an abstract class.

public interface StackInterface {public boolean isEmpty();public int size();public void push(Object item);public Object top() ;public void pop();

}

Page 21: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.21

Interfaces in Java

Interfaces reduce coupling between objects and their clients:

> A class can implement multiple interfaces— ... but can only extend one parent class

> Clients should depend on an interface, not an implementation— ... so implementations don’t need to extend a specific class

Define an interface for any data abstraction that will have more than one implementation

Page 22: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.22

Stacks as Linked Lists

A Stack can easily be implemented by a linked data structure:

stack = new Stack();stack.push(6);stack.push(7);stack.push(3);stack.pop();

Page 23: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.23

LinkStack Cells

We can define the Cells of the linked list as an inner class within LinkStack:

public class LinkStack implements StackInterface {private Cell top;private class Cell {

Object item;Cell next;Cell(Object item, Cell next) {

this.item = item;this.next = next;

}}...

}

Page 24: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.24

Private vs Public instance variables

When should instance variables be public? Always make instance variables private or protected.

The Cell class is a special case, since its instances are strictly private to LinkStack!

Page 25: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.25

LinkStack abstraction

The constructor must construct a valid initial state:

public class LinkStack implements StackInterface {...private int size;public LinkStack() {

// Establishes the class invariant.top = null;size = 0;

}...

Page 26: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.26

Class Invariants

A class invariant is any condition that expresses the valid states for objects of that class:

> it must be established by every constructor> every public method

— may assume it holds when the method starts— must re-establish it when it finishes

Stack instances must satisfy the following invariant:> size ≥ 0> ...

Page 27: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.27

LinkStack Class Invariant

A valid LinkStack instance has an integer size, and a top that points to a sequence of linked Cells, such that:— size is always ≥ 0— When size is zero, top points nowhere (== null)— When size > 0, top points to a Cell containing the top item

Page 28: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

When to check invariants?

> In principle, check invariants:— at the end of each constructor— at the end of every public mutator

© Oscar Nierstrasz

Design by Contract

28

Page 29: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz 29

Roadmap

> Contracts> Stacks> Design by Contract> A Stack Abstraction> Assertions> Example: balancing parentheses

Safety Patterns

Page 30: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.30

Assertions

> An assertion is a declaration of a boolean expression that the programmer believes must hold at some point in a program. — Assertions should not affect the logic of the program— If an assertion fails, an exception is raised

x = y*y;assert x >= 0;

Page 31: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.31

Assertions

Assertions have four principle applications:1. Help in writing correct software

— formalizing invariants, and pre- and post-conditions

2. Documentation aid— specifying contracts

3. Debugging tool— testing assertions at run-time

4. Support for software fault tolerance— detecting and handling failures at run-time

Page 32: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.32

Assertions in Java

assert is a keyword in Java since version 1.4

will raise an AssertionError if expression is false.— NB: Throwable Exceptions must be declared; Errors need not

be!

Be sure to enable exceptions in eclipse! (And set the vm flag -enableassertions [-ea])

assert expression;

Page 33: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.33

Enabling assertions in eclipse

Page 34: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.34

Checking pre-conditions

Assert pre-conditions to inform clients when they violate the contract.

When should you check pre-conditions to methods? Always check pre-conditions, raising exceptions if they

fail.

public Object top() {assert(!this.isEmpty()); // pre-conditionreturn top.item;

}

NB: This is all you have to do!

Page 35: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.35

Checking class invariants

Every class has its own invariant:

protected boolean invariant() {return (size >= 0) &&

( (size == 0 && this.top == null)|| (size > 0 && this.top != null));

}

Why protected and not private?

Page 36: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.36

Checking post-conditions

Assert post-conditions and invariants to inform yourself when you violate the contract.

When should you check post-conditions? Check them whenever the implementation is non-trivial.

public void push(Object item) {top = new Cell(item, top);size++;assert !this.isEmpty(); // post-conditionassert this.top() == item; // post-conditionassert invariant();

}NB: This is all you have to do!

Page 37: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz 37

Roadmap

> Contracts> Stacks> Design by Contract> A Stack Abstraction> Assertions> Example: balancing parentheses

Safety Patterns

Page 38: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.38

Example: Balancing Parentheses

Problem:> Determine whether an expression containing

parentheses ( ), brackets [ ] and braces { } is correctly balanced.

Examples:> balanced:

> not balanced:

if (a.b()) { c[d].e(); }else { f[g][h].i(); }

((a+b())

Page 39: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.39

A simple algorithm

Approach: > when you read a left parenthesis, push the matching

parenthesis on a stack> when you read a right parenthesis, compare it to the

value on top of the stack— if they match, you pop and continue— if they mismatch, the expression is not balanced

> if the stack is empty at the end, the whole expression is balanced, otherwise not

Page 40: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.40

Using a Stack to match parentheses

Sample input: “( [ { } ] ]”

Input Case Op Stack

( left push ) )

[ left push ] )]

{ left push } )]}

} match pop )]

] match pop )

] mismatch ^false )

Page 41: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.41

The ParenMatch class

A ParenMatch object uses a stack to check if parentheses in a text String are balanced:

public class ParenMatch {private String line;private StackInterface stack;

public ParenMatch (String aLine, StackInterface aStack){

line = aLine;stack = aStack;

}

Page 42: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.42

A declarative algorithm

We implement our algorithm at a high level of abstraction:

public boolean parenMatch() {for (int i=0; i<line.length(); i++) {

char c = line.charAt(i);if (isLeftParen(c)) { // expect matching right paren later

stack.push(matchingRightParen(c)); // Autoboxed to Character} else {

if (isRightParen(c)) {// empty stack => missing left parenif (stack.isEmpty()) { return false; }if (stack.top().equals(c)) { // Autoboxed

stack.pop();} else { return false; } // mismatched paren

}}

}return stack.isEmpty(); // not empty => missing right paren

}

Page 43: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.43

Ugly, procedural version

public boolean parenMatch() {char[] chars = new char[1000]; // ugly magic numberint pos = 0;for (int i=0; i<line.length(); i++) {

char c = line.charAt(i);switch (c) { // what is going on here?case '{' : chars[pos++] = '}'; break;case '(' : chars[pos++] = ')'; break;case '[' : chars[pos++] = ']'; break;case ']' : case ')' : case '}' :

if (pos == 0) { return false; }if (chars[pos-1] == c) { pos--; }else { return false; }break;

default : break;}

}return pos == 0; // what is this?

}

Page 44: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.44

Helper methods

The helper methods are trivial to implement, and their details only get in the way of the main algorithm.

private boolean isLeftParen(char c) {return (c == '(') || (c == '[') || (c == '{');

}

private boolean isRightParen(char c) {return (c == ')') || (c == ']') || (c == '}');

}

Page 45: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.45

Running parenMatch

public static void parenTestLoop(StackInterface stack) {BufferedReader in =

new BufferedReader(new InputStreamReader(System.in));String line;try {

System.out.println("Please enter parenthesized expressions to test");System.out.println("(empty line to stop)");do {

line = in.readLine();System.out.println(new ParenMatch(line, stack).reportMatch());

} while(line != null && line.length() > 0);System.out.println("bye!");

} catch (IOException err) {} catch (AssertionException err) {

err.printStackTrace();}

}

Page 46: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.46

Running ParenMatch.main ...

Which contract has been violated?

Please enter parenthesized expressions to test(empty line to stop)(hello) (world)"(hello) (world)" is balanced()"()" is balancedstatic public void main(String args[]) {"static public void main(String args[]) {" is not balanced()"()" is not balanced}"}" is balanced

"" is balancedbye!

Page 47: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.47

What you should know!

What is an abstract data type? What is the difference between encapsulation and

information hiding? How are contracts formalized by pre- and post-

conditions? What is a class invariant and how can it be specified? What are assertions useful for? What situations may cause an exception to be raised? How can helper methods make an implementation more

declarative?

Page 48: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

© Oscar Nierstrasz

Design by Contract

2.48

Can you answer these questions?

When should you call super() in a constructor? When should you use an inner class? What happens when you pop() an empty java.util.Stack?

Is this good or bad? What impact do assertions have on performance? Can you implement the missing LinkStack methods?

Page 49: 3. Design by Contract. Design by Contract © Oscar Nierstrasz Design by Contract 2.2 Bertrand Meyer, Object-Oriented Software Construction, Prentice Hall,

License

© Oscar Nierstrasz 49

Attribution-ShareAlike 2.5You are free:• to copy, distribute, display, and perform the work• to make derivative works• to make commercial use of the work

Under the following conditions:

Attribution. You must attribute the work in the manner specified by the author or licensor.

Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one.

• For any reuse or distribution, you must make clear to others the license terms of this work.• Any of these conditions can be waived if you get permission from the copyright holder.

Your fair use and other rights are in no way affected by the above.

http://creativecommons.org/licenses/by-sa/2.5/

Design by Contract