CS189A/172 - Winter 2008 Lecture: Design by Contract.

Slides:



Advertisements
Similar presentations
Where Agile Meets Formal Methods
Advertisements

Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 18 Program Correctness To treat programming.
272: Software Engineering Fall 2008 Instructor: Tevfik Bultan Lecture 2: Design by Contract.
Design by Contract.
Building Bug-Free O-O Software: An Introduction to Design By Contract A presentation about Design By Contract and the Eiffel software development tool.
272: Software Engineering Fall 2012
Semantics Static semantics Dynamic semantics attribute grammars
 Both System.out and System.err are streams—a sequence of bytes.  System.out (the standard output stream) displays output  System.err (the standard.
ISBN Chapter 3 Describing Syntax and Semantics.
1 Design by Contract Building Reliable Software. 2 Software Correctness Correctness is a relative notion  A program is correct with respect to its specification.
ACM/JETT Workshop - August 4-5, :Inheritance and Interfaces.
Feb 2003 R McFadyen1 Contracts (Ch 13) Used to help understand requirements more completely based on assertions; assertions are applicable to any.
Jan 2005 Ron McFadyen1 Contracts Used to help understand requirements more completely (and so may not always be necessary) based on assertions;
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 18 Program Correctness To treat programming.
Software Testing and Quality Assurance
OOP in Java Nelson Padua-Perez Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
Static and Dynamic Contract Verifiers For Java Hongming Liu.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Lecture 4: The Interface of a Class.
Chair of Software Engineering Einführung in die Programmierung Introduction to Programming Prof. Dr. Bertrand Meyer Lecture 4: The Interface of a Class.
OOP #10: Correctness Fritz Henglein. Wrap-up: Types A type is a collection of objects with common behavior (operations and properties). (Abstract) types.
Copyright © 2006 The McGraw-Hill Companies, Inc. Programming Languages 2nd edition Tucker and Noonan Chapter 18 Program Correctness To treat programming.
September 2002 R McFadyen1 Domain Model Use Case Model text diagram SSD System operation contracts Design Model Figure 13.3.
1 Introduction to: Design by Contract Fall 2005 OOPD John Anthony.
Design by Contract David Talby. Software Correctness When is a class correct? – It ’ s a relative concept; what is required? – But it ’ s the correct.
Data Abstraction and Object- Oriented Programming CS351 – Programming Paradigms.
Describing Syntax and Semantics
Eiffel Language and Design by Contract Contract –An agreement between the client and the supplier Characteristics –Expects some benefits and is prepared.
Chapter 10 Classes Continued
Adding Contracts to Ada Ehud Lamm Adding Design By Contract to Ada.
1 © Wolfgang Pelz Design by Contract Design by Contract™ Based on material drawn from: Bertrand.
Subclasses and Subtypes CMPS Subclasses and Subtypes A class is a subclass if it has been built using inheritance. ▫ It says nothing about the meaning.
Computer Science 340 Software Design & Testing Design By Contract.
Component-Based Software Engineering Components and Interfaces Paul Krause.
Ranga Rodrigo. Class is central to object oriented programming.
Introduction To System Analysis and design
Comparison of OO Programming Languages © Jason Voegele, 2003.
1 Abstraction  Identify important aspects and ignore the details  Permeates software development programming languages are abstractions built on hardware.
Analyzing the Requirements with Formal Specifications Vienna Development Method Specification Language (VDM-SL) Book: Formal Software Development From.
Tammy Dahlgren with Tom Epperly, Scott Kohn, and Gary Kumfert Center for Applied Scientific Computing Common Component Architecture Working Group October.
Design by Contract in Java Concept and Comparison.
SWE 619 © Paul Ammann Procedural Abstraction and Design by Contract Paul Ammann Information & Software Engineering SWE 619 Software Construction cs.gmu.edu/~pammann/
111 Protocols CS 4311 Wirfs Brock et al., Designing Object-Oriented Software, Prentice Hall, (Chapter 8) Meyer, B., Applying design by contract,
More About Classes Ranga Rodrigo. Information hiding. Copying objects.
Designing Classes Prelude © 2015 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved. Data Structures and Abstractions with Java, 4e Frank.
Design by Contract Ranga Rodrigo based on Mark Priestley's Lectures.
1 Devon M. Simmonds, Computer Science Department Design by Contract Devon M. Simmonds Computer Science Department University of North Carolina, Wilmington.
 In the java programming language, a keyword is one of 50 reserved words which have a predefined meaning in the language; because of this,
ANU COMP2110 Software Design in 2003 Lecture 10Slide 1 COMP2110 Software Design in 2004 Lecture 12 Documenting Detailed Design How to write down detailed.
L13: Design by Contract Definition Reliability Correctness Pre- and post-condition Asserts and Exceptions Weak & Strong Conditions Class invariants Conditions.
SWE 4743 Abstract Data Types Richard Gesick. SWE Abstract Data Types Object-oriented design is based on the theory of abstract data types Domain.
Interfaces F What is an Interface? F Creating an Interface F Implementing an Interface F What is Marker Interface?
PROGRAMMING PRE- AND POSTCONDITIONS, INVARIANTS AND METHOD CONTRACTS B MODULE 2: SOFTWARE SYSTEMS 13 NOVEMBER 2013.
CSSE501 Object-Oriented Development. Chapter 10: Subclasses and Subtypes  In this chapter we will explore the relationships between the two concepts.
DBC NOTES. Design By Contract l A contract carries mutual obligations and benefits. l The client should only call a routine when the routine’s pre-condition.
Object Design More Design Patterns Object Constraint Language Object Design Specifying Interfaces Review Exam 2 CEN 4010 Class 18 – 11/03.
 Description of Inheritance  Base Class Object  Subclass, Subtype, and Substitutability  Forms of Inheritance  Modifiers and Inheritance  The Benefits.
Design by Contract. The Goal Ensure the correctness of our software (correctness) Recover when it is not correct anyway (robustness) Correctness: Assertions.
Interfaces CMSC 202. Public Interfaces Objects define their interaction with the outside world through the their public interface. A class' public interface.
© Bertrand Meyer and Yishai Feldman Notice Some of the material is taken from Object-Oriented Software Construction, 2nd edition, by Bertrand Meyer (Prentice.
Design by Contract Jim Fawcett CSE784 – Software Studio
Design by Contract Jim Fawcett CSE784 – Software Studio
Used to help understand requirements more completely
Design by Contract Fall 2016 Version.
Programming Languages 2nd edition Tucker and Noonan
Slides by Steve Armstrong LeTourneau University Longview, TX
Java Modeling Language (JML)
Assertions References: internet notes; Bertrand Meyer, Object-Oriented Software Construction; 4/25/2019.
Computer Science 340 Software Design & Testing
Programming Languages 2nd edition Tucker and Noonan
Presentation transcript:

CS189A/172 - Winter 2008 Lecture: Design by Contract

Design by Contract Design by Contract and the language that implements the Design by Contract principles (called Eiffel) was developed in Santa Barbara by Bertrand Meyer (was a UCSB professor at the time, now at ETH) Bertrand Meyer won the 2006 ACM Software System Award for Eiffel! – Award citation: “For designing and developing the Eiffel programming language, method and environment, embodying the Design by Contract approach to software development and other features that facilitate the construction of reliable, extendible and efficient software.” The company which supports the Eiffel language is located in Santa Barbara: –Eiffel Software ( The material in the following slides is mostly from the following paper: –“Applying Design by Contract,” B. Meyer, IEEE Computer, pp , October 1992.

Dependability and Object-Orientation An important aspect of object oriented design is reuse –For reusable components correctness is crucial since an error in a module can effect every other module that uses it Main goal of object oriented design and programming is to improve the quality of software –The most important quality of software is its dependability Design by contract presents a set of principles to produce dependable and robust object oriented software –Basic design by contract principles can be used in any object oriented programming language

What is a Contract? There are two parties: –Client which requests a service –Supplier which supplies the service Contract is the agreement between the client and the supplier Two major characteristics of a contract –Each party expects some benefits from the contract and is prepared to incur some obligations to obtain them –These benefits and obligations are documented in a contract document Benefit of the client is the obligation of the supplier, and vice versa.

What is a Contract? As an example let’s think about the contract between a client and a coffee shop PartyObligationsBenefits ClientOrder a cup of coffee by choosing the size and the type from the menu at the coffee shop and pay the corresponding price in the menu in cash or with credit card. Get a cup of coffee. SupplierDeliver a cup of coffee in one of the sizes and types listed in the menu. Get cash, no need to worry about the types of coffee that are not in the list, or unpaid orders or bounced checks.

What is a Contract? A contract document protects both sides –It protects the client by specifying how much should be done to get the benefit. The client is entitled to receive a certain result. –It protects the contractor by specifying how little is acceptable. The contractor must not be liable for failing to carry out tasks outside of the specified scope. If a party fulfills its obligations it is entitled to its benefits –No Hidden Clauses Rule: no requirement other than the obligations written in the contract can be imposed on a party to obtain the benefits

How Do Contracts Relate to Software Design? You are not in law school, so what are we talking about? Here is the basic idea –One can think of pre and post conditions of a procedure as obligations and benefits of a contract between the client (the caller) and the supplier (the called procedure) Design by contract promotes using pre and post-conditions (written as assertions) as a part of module design Eiffel is an object oriented programming language that supports design by contract –In Eiffel the pre and post-conditions are written using require and ensure constructs, respectively

Design by Contract in Eiffel An Eiffel procedure is in the form: procedure_name(argument declarations) is -- Header comment require Precondition do Procedure body ensure Postcondition end An example: put_child(new_child: NODE) is -- Add new to the children of current node require new_child /= Void do... Insertion algorithm... ensure new_child.parent = Current; child_count = old child_count + 1 end -- put_child Current refers to the current instance of the object (this in Java) Old keyword is used to denote the value of a variable on entry to the procedure Note that “=“ is the equality operator (= = in Java) and “/=“ is the inequality operator (!= in Java)

The put_child Contract The put_child contract in English would be something like the table below. –Eiffel language enables the software developer to write this contract formally using require and ensure constructs PartyObligationsBenefits ClientUse as argument a reference, say new_node, to an existing object of type Node. Get an updated tree where the Current node has one more child than before; new_child now has Current as its parent. SupplierInsert new node as required. No need to do anything if the argument is not attached to an object.

Contracts The pre and postconditions are assertions, i.e., they are expressions which evaluate to true or false –The precondition expresses the requirements that any call must satisfy –The postcondition expresses the properties that are ensured at the end of the procedure execution If there is no precondition or postcondition, then the precondition or postcondition is assumed to be true (which is equivalent to saying there is no pre or postcondition)

Assertion Violations What happens if a precondition or a postcondition fails (i.e., evaluates to false) –The assertions can be checked (i.e., monitored) dynamically at run- time as an approach to debugging the software –A precondition violation would indicate a bug at the caller –A postcondition violation would indicate a bug at the callee Our goal is to prevent assertion violations from happening –The pre and postconditions are not supposed to fail if the software is correct hence, they differ from exceptions and exception handling –By writing the contracts explicitly, we are trying to avoid contract violations, (i.e, failed pre and postconditions)

Assertion Violations In the example below, if new_child = Void then the precondition fails. The procedure body is not supposed to handle the case where new_child = Void, that is the responsibility of the caller put_child(new_child: NODE) is -- Add new to the children of current node require new_child /= Void do... Insertion algorithm... ensure new_child.parent = Current; child_count = old child_count + 1 end -- put_child

Defensive Programming vs. Design by Contract Defensive programming is an approach that promotes putting checks in every module to detect unexpected situations This results in redundant checks (for example, both caller and callee may check the same condition) –A lot of checks makes the software more complex and harder to maintain In Design by Contract the responsibility assignment is clear and it is part of the module interface –prevents redundant checks –easier the maintain –provides a (partial) specification of functionality

Class Invariants A class invariant is an assertion that holds for all instances of the class –A class invariant must be satisfied after creation of every instance of the class –The invariant must be preserved by every method of the class, i.e., if we assume that the invariant holds at the method entry it should hold at the method exit –We can think of the class invariant as conjunction added to the precondition and postcondition of each method in the class For example, a class invariant for a binary tree could be (in Eiffel notation) invariant left /= Void implies (left.parent = Current) right /=Void implies (right.parent = Current)

Design by Contract and Inheritance Inheritance enables declaration of subclasses which can redeclare some of the methods of the parent class, or provide an implementation for the abstract methods of the parent class Polymorphism and dynamic binding combined with inheritance are powerful programming tools provided by object oriented languages –How can the Design by Contract can be extended to handle these concepts?

ClassA aMethod() ClassB Client aMethod() Inheritance: Preconditions If the precondition of the ClassB.aMethod is stronger than the precondition of the ClassA.aMethod, then this is not fair to the Client The code for ClassB may have been written after Client was written, so Client has no way of knowing its contractual requirements for ClassB

ClassA aMethod() ClassB Client aMethod() Inheritance: Postconditions If the postcondition of the ClassB.aMethod is weaker than the postcondition of the ClassA.aMethod, then this is not fair to the Client Since Client may not have known about ClassB, it could have relied on the stronger guarantees provided by the ClassA.aMethod

Inheritance Eiffel enforces the following –the precondition of a derived method to be weaker –the postcondition of a derived method to be stronger In Eiffel when a method overwrites another method the new declared precondition is combined with previous precondition using disjunction When a method overwrites another method the new declared postcondition is combined with previous postcondition using conjunction Also, the invariants of the parent class are passed to the derived classes – invariants are combined using conjunction

ClassA ClassB Client aMethod() In ClassA: invariant classInvariant aMethod() is require Precondition do Procedure body ensure Postcondition end In ClassB which is derived from ClassA: invariant newClassInvariant aMethod() is require newPrecondition do Procedure body ensure newPostcondition end The precondition of ClassB.aMethod is defined as: newPrecondition or Precondition The postcondition of ClassB.aMethod is defined as: newPostcondition and Postcondition The invariant of ClassB is classInvariant and newClassInvariant

Dynamic Design-by-Contract Monitoring Enforce contracts at run-time A contract –Preconditions of modules What conditions the module requests from the clients –Postconditions of modules What guarantees the module gives to clients –Invariants of the objects Precondition violation, the client is to blame –Generate an error message blaming the client (caller) Postcondition violation, the unit is to blame –Generate an error message blaming the server (callee)

jContractor: A Design-by-Contract Tool for Java jContractor is a design by contract tool for Java – –Developed here at UCSB by Murat Karaorman References: –“jContractor Crash Course”, Parker Abercrombie, –jContractor: Bytecode instrumentation techniques for implementing design by contract in Java." In Proceedings of Second Workshop on Runtime Verification, RV 02. Copenhagen, Denmark. July 26, –"jContractor: A Reflective Java Library to Support Design By Contract". In Proceedings of Meta-Level Architectures and Reflection, 2nd International Conference, Reflection '99. Saint- Malo, France, July The information in these slides are from the above resources.

jContractor Contracts in jContractor are written as Java methods that follow a simple naming convention. –Assertions are written as Java methods that return a boolean value jContractor provides runtime contract checking by instrumenting the bytecode of classes that define contracts. jContractor can –either add contract checking code to class files to be executed later, –or it can instrument classes at runtime as they are loaded. Contracts can be written in the class that they apply to, or in a separate contract class.

An Example Class class Stack implements Cloneable { private Stack OLD; private Vector implementation; public Stack () {... } public Stack (Object [] initialContents) {... } public void push (Object o) {... } public Object pop () {... } public Object peek () {... } public void clear () {... } public int size () {... } public Object clone () {... } private int searchStack (Object o) {... } }

Preconditions Precondition for method is written as a boolean method and its name is the method name followed by "_Precondition" A method's precondition is checked when execution enters the method. Precondition methods return boolean and take the same arguments as the non-contract method that they correspond to. protected boolean push_Precondition (Object o) { return o != null; } private boolean searchStack_Precondition (Object o) { return o != null; } protected boolean Stack_Precondition (Object [] initialContents) { return (initialContents != null) && (initialContents.length > 0); }

Postconditions Postcondition for method is written as a boolean method and its name is the method name followed by "_Postcondition" A method's postcondition is checked just before the method returns. Postcondition methods return boolean and take the same arguments as the non-contract method, plus an additional argument of the method's return type. This argument (called RESULT) must be the last in the list, and holds the value returned by the method. protected boolean push_Postcondition (Object o, Void RESULT) { return implementation.contains(o) && (size() == OLD.size() + 1); } protected boolean size_Postcondition (int RESULT) { return RESULT >= 0; } protected boolean Stack_Postcondition (Object [] initialContents, Void RESULT) { return size() == initialContents.length; }

Postconditions Postconditions may refer to the state of the object at method entry through the OLD instance variable. This variable must be declared private, and of the type of the class that contains it. If a class defines an OLD variable, it must also implement Cloneable and provide a clone() method. When execution enters a method, a clone of the object will be created and stored in OLD.

Invariants Class invariants are checked at the entry and exit of every public method in the class. The invariant is defined in a method called "_Invariant" that takes no arguments and returns a boolean. protected boolean _Invariant () { return size() >= 0; }

Separate Contract Classes Instead of writing contracts directly into your source code, you can write contract classes. Contract classes are given names with a "_CONTRACT" suffix, and do nothing but define contracts. class Stack_CONTRACT extends Stack { private Stack OLD; private Vector implementation; protected boolean Stack_Postcondition (Object [] initialContents, Void RESULT) { return size() == initialContents.length; } protected boolean Stack_Precondition (Object [] initialContents) { return (initialContents != null) && (initialContents.length > 0); } protected boolean push_Precondition (Object o) { return o != null; } protected boolean push_Postcondition (Object o, Void RESULT) { return implementation.contains(o) && (size() == OLD.size() + 1); } private int searchStack (Object o) { return 0; } private boolean searchStack_Precondition (Object o) { return o != null; } protected boolean _Invariant () { return size() >= 0; } }

Enforcing Contracts at Runtime There are two approaches –1) Use the jContractor class loader which instruments all classes containing contracts during class loading –2) Use jContractor library for object creation st = (Stack) jContractor.New() In the most recent version option 1 is used. To run a program with dynamic contract checking: –$ java jContractor MyProgram It is also possible to add contract checking code to class files so that they may be run with a usual Java runtime environment. –$ java jInstrument./MyProgram.class –$ java MyProgram

Assertion Evaluation Rule Since in jContractor one uses Java methods to write the assertions some problems may occur Consider the example below where invariant method makes a call to the method size(). When size method is called the invariant is checked at the entry which makes a call to size(), and this results in an infinite recursion class Stack {... public int size () {... } protected boolean _Invariant () { return size() >= 0; } }

Assertion Evaluation Rule To solve this problem, jContractor uses –Assertion Evaluation Rule: Only one contract can be checked at a time In the Stack example, the invariant will call size() and since there is a already a contract check in progress the invariant will not be checked on size() jContractor implements Assertion Evaluation Rule by maintaining a shared hash table of threads that are actively checking contracts. Before a thread checks a contract it queries the table to see if it is already checking one.

Inheritance in jContractor In jContractor contract of a method can have four parts: –Internal Contract: Defined in the same class as the method –External Contract: Defined in a separate contract class –Superclass Contract: Inherited from the superclass –Interface Contracts: Inherited from interfaces During contract checking for a method all these parts are checked jContractor follows the same inheritance principle as Eiffel –a subclass method can only weaken the precondition and strengthen the postcondition

Combining Contracts class Foo extends SuperFoo implements FooInterface { void m() {...} boolean m_Precondition() {...} boolean m_Postcondition() {..} boolean _Invariant() {...} } class Foo_CONTRACT { boolean m_Precondition() {...} boolean m_PostCondition() {...} boolean _Invariant() {...} } class SuperFoo { void m() {...} boolean m_Precondition() {...} boolean m_PostCondition() {...} boolean _Invariant() {...} } class FooInterface_CONTRACT { boolean m_Precondition() {...} boolean m_PostCondition() {...} boolean _Invariant() {...} } // Instrumented version class Foo extends SuperFoo implements FooInterface { void m() { Check invariant and precondition Original method body Check invariant and postcondition } boolean m_Precondition() { return Interface preconditions || super.m_Precondition() || (External precondition && Original precondition) } boolean m_Postcondition() { return Interface postconditions && super.m_Postcondition(RESULT) && External postcondition && Original postcondition } boolean _Invariant() { return Interface Invariants && super._Invariant() && (External invariant && Original invariant) }

Writing Contacts in OCL Object Constraint Language (OCL) is a specification language that supports specification of contracts (i.e., pre, post conditions and invariants) in UML class diagrams. OCL constraints have formal syntax and semantics –their interpretation is unambiguous OCL can be used to add precision to UML diagrams There are tools which check OCL constraints.: –USE (A UML-based Specification Environment) –Enables analysis of UML diagrams before implementation

Writing Contracts in UML + OCL LoyaltyAccount points: Integer earn(i: Integer) burn(i: Integer) isEmpty(): Boolean { points >= 0 } > points = - i class invariant postcondition for burn operation > result = (points=0) > points >= i and i >= 0 precondition for burn operation > points = + i > i >= 0

Writing Contracts in JML Java Modeling Language (JML) is an annotation language for Java that enables specification of contracts for Java classes as annotations. JML can be used to write pre, post-conditions and invariants for Java classes There are static contract checking tools (such as ESC Java) which check JML contracts statically –Stati verification tools can check contracts at compile-time rather than runtime. JContractor checks contracts at runtime. –However, static checking is computationally very expensive so static analysis tools can check a restricted set of properties.