1 / 35

Internet Software Development

Dive into the concept of interfaces as contracts in software development, focusing on specifying pre- and post-conditions. Explore the benefits of future proofing and ensuring non-functional requirements.

nolte
Download Presentation

Internet Software Development

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Internet Software Development Components and Interfaces Paul Krause

  2. Lecture 11 - Interfaces Contents • Interfaces as Contracts • Future Proofing • Non-functional requirements • Specifying Pre- and Post-conditions • Using assertions to check Conditions

  3. A B1 B2 Components and Interfaces A requires certain functionality to fulfil its obligations. B1 and/or B2 provide that functionality. An interface mediates between clients and providers.

  4. Interfaces as contracts • Can view an interface specification as a “contract” between the client and a provider • So the interface specification must state: • What the client needs to do • What a provider can rely on • What a provider must promise in return • What the client can rely on

  5. Pre- and Post-Conditions • Pre-conditions: • What the client must establish before calling the operation • The provider can rely on this condition being true whenever the operation is called • Post-conditions: • What the provider must establish before returning to the client • The client can rely on this condition being true whenever the call to the operation returns

  6. Associate pre- and post-conditions to every method in the interface Example public interface Directory { public void addEntry(String name, File file); // pre name != “” and file != null // post File file = map.get(name) }

  7. Lecture 11 - Interfaces Contents • Interfaces as Contracts • Future Proofing • Non-functional requirements • Specifying Pre- and Post-conditions • Using assertions to check Conditions

  8. Future proofing • An interface acts as a contract between client and provider • Suppose an interface remains unchanged • Is there any scope for revising an implementation without introducing a risk of “breaking” old clients? • Ans: The revised implementation may require less and/or provide more

  9. Future Proofing public interface Arithmetic { public double processNumbers(double x, double y); // pre x > 5 and y > 5 // postif r = this.processNumbers(x, y) then r > 10 } public double processNumbers(double x, double y) { if ((x < 0) || (y < 0)) throw new IllegalArgumentException(“Args must be >=0”); return x + y + 20.0; }

  10. Future Proofing x > 5 and y > 5 implies x >=0 and y >= 0 • The new implementation requires less than the interface • The implementation “weakens” the pre-conditions return >= 20 implies return > 10 • The new implementation provides more than the interface specifies • The implementation “strengthens” the post-conditions

  11. Lecture 11 - Interfaces Contents • Interfaces as Contracts • Future Proofing • Non-functional requirements • Specifying Pre- and Post-conditions • Using assertions to check Conditions

  12. What else can go wrong? public interface Directory { public void addEntry(String name, File file); // pre name != “” and file != null // post File file = map.get(name) } • strictly this is only a guarantee of partial correctness • the operation either terminates correctly or does not terminate at all! • progress conditions: • something guaranteeing the pre-condition will lead to something guaranteeing the post-condition

  13. Non-functional requirements • We have seen how respecting pre- and post-conditions reduces the risk of a revised implementation “breaking” a client • But are changes in the functional behaviour the only way an implementation can break a client? • Consider a Maths interface, with methods to support an animation package • What about a new implementation that improves accuracy?

  14. Specifying the Service Level Now add guarantees for levels of: • Availability; • Mean time between failures; • Mean time to repair; • Throughput; • Data safety; • Capacity.

  15. Time and Space Requirements • Specifying execution time is platform dependent • So what can realistically be included in a contract? • Could use complexity bounds • E.g. perform an operation on n elements in n log n time, using at most log n additional storage cells • A client can then determine the absolute time and space bounds for a given provider on a given platform

  16. Lecture 11 - Interfaces Contents • Interfaces as Contracts • Future Proofing • Non-functional requirements • Specifying Pre- and Post-conditions • Using assertions to check Conditions

  17. Back to interfaces? • Design Guideline: “When the functionality supported by a class can be implemented in different ways, it is advisable to separate the interface from the implementation” Xiaoping Jia • And we can cast an object into its interface type if we only want to access its services

  18. List as an example public interface List { public int size( ); public boolean isEmpty( ); public Object element(int i); public Object head( ); public Object last( ); public void insert(Object item, int i); public void insertHead(Object item); public void insertLast(Object item); // more… }

  19. Implementations of List • We can have several different implementations of the List interface: public class LinkedList implements List { <body of Linked List here> } • or: public class DynamicArray implements List { <body of DynamicArray here> }

  20. Interfaces as Contracts • Interfaces specify the types of their associated methods, but say nothing about their behaviour • We can improve on that!

  21. Pre- and Post-Conditions • Pre-conditions: • What the client must establish before calling the operation • The provider can rely on this condition being true whenever the operation is called • Post-conditions: • What the provider must establish before returning to the client • The client can rely on this condition being true whenever the call to the operation returns

  22. Stage 1: Documentation • Use “@pre” and “@post” as special tags for preconditions and postconditions: /** * @pre precondition * @post postcondition • */ public void method1 { // … }

  23. A boring example /** * Returns the number of elements in a list * * @pre true * @post @nochange */ public int size( );

  24. A more interesting example /** * Returns the i-th element in the list * * @pre i >= 0 && i < size( ) * @post @nochange */ public Object element(int i);

  25. Other logical expressions ==> logical implication <==> logical equivalence @forall x : Range @ Expression Universally quantified expression @exists x : Range @ Expression [m … n] Integer range from m to n

  26. A nasty example /** * Inserts a new element into a list at the i-th position * * @pre item != null && i >= 0 && i <= size( ) * @post size( ) == size( )@pre + 1 * @post @forall k : [0 .. size( ) - 1] @ * (k < i ==> element(k)@pre == element(k)) && * (k == i ==> item@pre == element(k)) && * (k > i ==> element(k-1)@pre == element(k) */ public void insert(Object item, int i);

  27. An exercise Use this method to specify the interface to a method that inserts a new element to the head of a list

  28. Solution /** * Inserts a new element at the head of a list * * @pre item != null * @post size( ) == size( )@pre + 1 * @post item@pre == element(0) * @ post @forall k : [1 .. size( ) - 1] @ element(k-1)@pre == element(k) */ public void insertHead(Object item);

  29. How does this help? • As this stands, the comments provide guidance only • They prescribe what should be done, but are agnostic about whether a specific implementation satisfies them • We can, however, provide run-time checks through the use of Assertions

  30. Lecture 11 - Interfaces Contents • Interfaces as Contracts • Future Proofing • Non-functional requirements • Specifying Pre- and Post-conditions • Using assertions to check Conditions

  31. Assertions are? • Boolean conditions that are inserted into a program at strategic points • We expect them to be true when the flow of control reaches each respective point • If an assertion is true, it has no effect and the flow of control continues • If an assertion is false, then execution stops at that point and an AssertionError is thrown

  32. Where do you put them? • Assertions on the preconditions of a method should be placed immediately on entry to the method • Assertions on postconditions should be placed just prior to the return statement • But remember that any references to the pre-state of variables must be instantiated upon entry to the method

  33. LinkedList implements List /** * @pre item != null && i >= 0 && i <= size( ) * @post size( ) == size( )@pre + 1 */ public void insert(Object item, int i) { assert item != null && i >= 0 && i <= size( ); int size_pre = size( ); // // < body of method here … > // int size_post = size( ); assert size_post == size_pre + 1; }

  34. Extra points to note • Need JDK 1.4 or higher, and compile using: • javac -source 1.4 Class.java • Execute the class with: • java -ea Class • In order to fully assert the postconditions, we usually need to clone an instance of a class before we modify it • Use of assertions derived from preconditions is known as Defensive Programming • Use of assertions derived from postconditions is also valuable in testing and debugging

  35. Summary • We have discussed the use of interfaces when there may be multiple ways of implementing certain functionality • Including statements of pre- and post-conditions in the comment lines for each method declaration makes a richer specification • Including the pre- and post-conditions in the implementation of each interface adds a further level of rigour (but has limited support in Java at present)

More Related