Design-by-Contract
• An approach to designing pieces of software (―components‖) so they not only ―fit together‖ in the sense that the compiler is happy, but that they compute together • This requires defining behavior, not just syntax
What is a “Contract”?
• Contract (aka specification) is a set of ―interaction rules‖ that govern responsibilities of clients and implementers wrt a (shared) interface
• Non-software example: the this garbage warranty on your is where a contract resides disposal is not unconditional; it won’t apply if you try to chew up diamonds in it!
NaturalClient
<> INatural
Natural_1
The Parts of a Contract (1)
• For a new program type, contract says how client and implementer should think about the values of objects of that type INatural contract tells client this • Example:
INatural n = new Natural_1 ();
? 0
n
The Parts of a Contract (2)
• For each new method, contract says what client is responsible for making true (i.e., what implementer may assume is true) about incoming object values contract says INatural multiplyByC requires that • Example:
n.multiplyByC (d); 0 <= d < C (this assertion is called the precondition)
The Parts of a Contract (3)
INatural contract says multiplyByC ensures that • For each new method, contract says what •preserves x *means x = #x n = #n C + d client may assume •alters preserveswhatd change is truemeans x d — = #d x (i.e., might and — by •produces means x might implementer is responsiblexfor making true) (this assertion is called change, but #x has no about outgoing object the postcondition) effect values on its new value
• Example:
n.multiplyByC (d);
• Note that parameter modes are part of the contract!
Uses of a Contract
• You can use the contract to:
• record the values of program variables and objects in a client program • predict the effects of method calls made by the client • assign blame when a method call does not behave as the contract specifies
• Without a contract, there is no way to do any of these things!
this column is used to track statements in program
Tracing Table is used to this column
track variables in program
• Tracing table is a device to make this easy:
Statement State d=3 n –> 789 n.multiplyByC (d); = means variable –>has this variable means value (as in mathematics) refers to an object d = 3that has this value n –> 7893
Assigning Blame for Trouble
Statement
State d = –4 n –> 789
n.multiplyByC (d);
whose fault? why?
wrong value(s), or ―uncaught exception‖
Assigning Blame for Trouble
Statement
State d=1 n –> 789
n.multiplyByC (d);
whose fault? why?
wrong value(s), or ―uncaught exception‖
To Check or Not to Check?
• In normal situations, there is no contract checking code — there is no need for it! • However, for testing and debugging, such code can be helpful
• Testing is the process of trying to force software to exhibit its defects (violations of contracts) • Debugging is the process of identifying and fixing such defects
Where Do You Check?
• If you want to check at run-time for contract violations, where should the code go?
• In the client, before (and after) every call? • In the implementation, before (and after) every call? • In both? • Somewhere else?
Checking Components
<> INatural <> INaturalC + multiplyByC ( int k)
interface for specification of multiplyByC checking component overrides same method in INatural
Natural_1
Natural_1C + multiplyByC ( int k)
layered implementation in which body of multiplyByC overrides same method in Natural_1
Code for INaturalC
package natural; public interface INaturalC extends INatural { public void multiplyByC (int k); } only INatural methods with preconditions are overridden; they must have the same signatures as in INatural
Specification of multiplyByC
public void multiplyByC (int k);
Specification:
alters this preserves k ensures if (0 <= k < C) then this = #this * C + k else [AssertionError]
notice how the precondition of the original multiplyByC is in this case, multiplyByC incorporated in the postcondition throws a special exception of the checking multiplyByC (you don’t declare it!)
Code for Natural_1C
package natural; special assert statement (available as of Java 1.4) public class Natural_1C extends Natural_1 raises AssertionError exception if the condition is false implements INaturalC super names the class that this class extends, i.e., { aNatural_1 same method in call to the k) public void multiplyByC (int — which avoids infinite recursion! superclass is called delegation { assert 0 <= k : "0 <= k"; assert k < this.getC () : "k < C"; super.multiplyByC (k); } }
Using assert
• As of this time (10/2003), assert is so new that you need a special switch to compile it
• You use a special switch to ―turn on‖ checking (for a whole program, or class-by-class)
• To recognize assert when compiling:
javac -source 1.4 TestNatural.java
• To run the program:
java -ea TestNatural