Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Refactoring with Contracts Shmuel Tyszberowicz School of Computer Science The Academic College of Tel Aviv Yaffo Maayan Goldstein School of Computer.

Similar presentations


Presentation on theme: "1 Refactoring with Contracts Shmuel Tyszberowicz School of Computer Science The Academic College of Tel Aviv Yaffo Maayan Goldstein School of Computer."— Presentation transcript:

1 1 Refactoring with Contracts Shmuel Tyszberowicz School of Computer Science The Academic College of Tel Aviv Yaffo Maayan Goldstein School of Computer Science Tel Aviv University Yishai A. Feldman Efi Arazi School of Computer Science The Interdisciplinary Center Herzliya

2 2 Is Software Development a Pain?? Of course not! It's fun! But the requirements are always changing… Dan Berry (2002): Every development method has a fatal flaw, a pain that developers postpone and avoid In XP, this is refactoring For us, it is unit testing!

3 3 What Seems to be the Problem? Writing all the necessary tests is hard work Unit tests need to change with almost any change in the code: Functionality Refactoring Test data generation needed

4 4 Solution Tests should be responsible for exercising the code The correctness is to be checked by the contract!

5 5 Agenda Introduction Refactoring Examples Crepe Recipe Summary

6 6 Agenda Introduction Refactoring Examples Crepe Recipe Summary

7 7 Design by Contract A practical methodology for evolving code together with its specification Class invariants, method preconditions and postconditions: Precondition binds clients Postcondition obliges suppliers Invariant is a consistency constraint

8 8 Behavioral Subtyping (Liskov) Invariants and postconditions in subclasses May only be strengthened Computed as conjunctions (ANDed) Preconditions in subclasses May only be weakened Computed as disjunctions (ORed)

9 9 Extreme Design by Contract Correctness checked by contract Of course, contract may need to change when code changes… But Contract expresses intent of code! Contracts can be refactored systematically Contract refactoring can be partially automated Crepe == Contract Refactoring Plugin for Eclipse

10 10 Agenda Introduction Refactoring Examples Crepe Recipe Summary

11 11 ReadyQueue (1) /** @inv size() >= 0 */ public class ReadyQueue { final private List elements = new LinkedList(); public int size() { /*... */ } /** @pre job != null * @pre job.status() == Job.READY * @post elements.get(0) == job * @post size() == $prev(size()) + 1 */ public void insert(Job job) { /*... */ }

12 12 ReadyQueue (2) /** @pre size() > 0 * @post size() == $prev(size()) - 1 */ public void remove() { /*... */ } /** @post (size() == 0) == ($ret == null) */ public Job top() { /*... */ } }

13 13 FreeJobs (1) /** @inv size() >= 0 */ public class FreeJobs { final private List elements = new LinkedList(); public int size() { /*... */ } /** @pre job != null * @pre job.status() == Job.INACTIVE * @post top() == job * @post size() == $prev(size()) + 1 */ public void insert(Job job) { /*... */ } READY elements.get(0)= = job

14 14 FreeJobs (2) /** @pre size() > 0 * @post size() == $prev(size()) - 1 */ public void remove() { /*... */ } /** @pre size() > 0 * @post $ret != null * @post $ret.status() == Job.INACTIVE */ public Job top() { /*... */ } } @post (size() == 0) == ($ret == null)

15 15 Example: Extract Superclass JobDispenser ReadyQueueFreeJobs ReadyQueue FreeJobs

16 16 Extract Superclass Refactoring (1) /** @inv size() >= 0 */ public abstract class JobDispenser { protected List elements = new LinkedList(); /** @pre false * @post size() == 1 + $prev(size()) */ public abstract void insert(Job job); Contradictory preconditions in subclasses: @pre job.status() == Job.READY @pre job.status() == Job.INACTIVE

17 17 Extract Superclass Refactoring (2) /** @pre size() > 0 * @post 1 + size() == $prev(size()) */ public abstract void remove(); /** @pre size() > 0 */ public abstract Job top(); public abstract int size(); } Precondition from FreeJobs, but not from ReadyQueue Common postconditions (Form slightly changed by theorem-prover)

18 18 Changes: ReadyQueue (1) /** @inv size() >= 0 */ public class ReadyQueue { /** @pre job != null * @pre job.status() == Job.READY * @post elements.get(0) == job * @post size() == $prev(size()) + 1 */ public void insert(Job job) { /*... */ }

19 19 Changes: ReadyQueue (2) /** @pre size() > 0 * @post size() == $prev(size()) - 1 */ public void remove() { /*... */ } public int size() { /*... */ } /** @pre size() == 0 * @post (size() == 0) == ($ret == null) */ public Job top() { /*... */ } } Crepe reasoning: true size() <= 0 size() == 0 Complement size() > 0 from superclass Simplify with invariant size() >= 0

20 20 Changes: FreeJobs (1) /** @inv size() >= 0 */ public class FreeJobs { /** @pre job != null * @pre job.status() == Job.INACTIVE * @post top() == job * @post size() == $prev(size()) + 1 */ public void insert(Job job) { /*... */ }

21 21 Changes: FreeJobs (2) /** @pre size() > 0 * @post size() == $prev(size()) - 1 */ public void remove() { /*... */ } /** @pre size() > 0 * @post $ret != null * @post $ret.status() == Job.INACTIVE */ public Job top() { /*... */ } public int size() { /*... */ } }

22 22 PriorityQueue /** @inv size() >= 0 */ public class PriorityQueue { /** @pre job != null * @pre job.status() == Job.READY * @pre job.priority()< Scheduler.current_priority() * @post size() == $prev(size()) + 1 */ public void insert(Job job) { /*... */ } //... }

23 23 Example: Add Inheritance ReadyQueue PriorityQueue ReadyQueue PriorityQueue

24 24 PriorityQueue vs. ReadyQueue /** @inv size() >= 0 */ public class ReadyQueue { /** @pre job != null * @pre job.status() == Job.READY * @post elements.get(0).equals(job) * @post size() == $prev(size()) + 1 */ public void insert(Job job) { /*... */ } } /** @inv size() >= 0 */ public class PriorityQueue { /** @pre job != null * @pre job.status() == Job.READY * @pre job.priority()< Scheduler.current_priority() * @post size() == $prev(size()) + 1 */ public void insert(Job job) { /*... */ } } Extra precondition Extra postcondition

25 25 Add Inheritance Cannot add inheritance relationship between two classes if, in the subclass, it causes Preconditions to be strengthened Invariants or postconditions to be weakened

26 26 Add Inheritance (Crepe)

27 27 Agenda Introduction Refactoring Examples Crepe Recipe Summary

28 28 The Crepe Recipe Use Eclipse ASTParser on assertions Parse the assertions in the Javadoc Convert to predicate form Use theorem prover (Mathematica) to verify relationships between assertions Find contract contradictions Compute the new contract Combine existing assertions to create new ones Compute contracts for arbitrary code (in preparation)

29 29 Combining Assertions Preconditions are conjoined and simplified Postconditions can be disjoined But, sometimes the most precise assertions are not best!

30 30 Extract Superclass - Postconditions class A { /** @post x >= 0 * @post x < 10 * @post y >= 0 * @post y < 10 */ void foo(); } class B { /** @post x >= 10 * @post x < 20 * @post y >= 10 * @post y < 20 */ void foo(); } A 1020 10 20 1020 10 20 B

31 31 Postconditions Computation A 1020 10 20 B A 1020 10 20 B class AB_strongest { /** @post * (x >= 0 && x < 10 && * y >= 0 && y < 10) || * (x >= 10 && x < 20 && * y >= 10 && y < 20) */ void foo(); } class AB_alternative { /** * @post x >= 0 * @post x < 20 * @post y >= 0 * @post y < 20 */ void foo(); }

32 32 Postconditions Computation class A extends AB_alternative { /** @post x < 10 * @post y < 10 */ void foo(); } class B extends AB_alternative { /** @post x >= 10 * @post y >= 10 */ void foo(); } A 1020 10 20 1020 10 20 B

33 33 Agenda Introduction Refactoring Examples Crepe Recipe Summary

34 34 Contracts Refactoring Statistics

35 35 Crepe Limitations Contract computation from arbitrary code Theorem prover (Mathematica): Supports only Booleans, Integers, Doubles, and Reals Fails to simplify some expressions using assumptions Not open source Assertions parsing Return type computations

36 36 Summary Design by Contract is an essential technique for producing high-quality code It is synergistic with Agile practices It helps develop with confidence Automation needed for the process of refactoring with contracts Crepe demonstrates such automating techniques

37 37 Questions?

38 38 Thank you!


Download ppt "1 Refactoring with Contracts Shmuel Tyszberowicz School of Computer Science The Academic College of Tel Aviv Yaffo Maayan Goldstein School of Computer."

Similar presentations


Ads by Google