Download presentation
Presentation is loading. Please wait.
1
Improved software quality through semantic descriptions (Skutt) Karlstad University Dept. of Computer Science 2000-05-09 Semla Design Method for use in Skywalker A Design Method with a Focus on Semantic Descriptions Karlstad University Ericsson Infotech AB NUTEK
2
Karlstad University Dept. of Computer Science Semla 2 page 2 Overview Data abstractions Weak and strong contracts Invariants
3
Karlstad University Dept. of Computer Science Semla 2 page 3 An example: A web connection We want to model a possible connection across a network –The other side may or may not be connected –If connected, the other side has a defined user name which is copied across to our program String* otherUser WebConnection the World Wide Web The other side userName
4
Karlstad University Dept. of Computer Science Semla 2 page 4 Data abstractions This is one possible model of a Web connection I want to expose the property otherUser There is a difference between –an empty user name, means "user name not known" –no user name, means "there is no other party" Suggest a class interface String* otherUser WebConnection
5
Karlstad University Dept. of Computer Science Semla 2 page 5 First attempt Class interface –String* getOtherUser(); What is the mental process? –Return whatever is stored in the object –The user of the object needs to be aware of the storage conventions String* otherUser WebConnection String* getOtherUser();
6
Karlstad University Dept. of Computer Science Semla 2 page 6 Contract for the first attempt Precondition: –true Postcondition: –result = the value of the otherUser variable What is gained in abstraction? –Nothing, possibly R/O –You might as well access the data directly String* otherUser WebConnection String* getOtherUser(); Calling style theOther = connection->getOtherUser(); if (theOther != NULL) doSomethingWith(theOther); else handleTheNoUserCase();
7
Karlstad University Dept. of Computer Science Semla 2 page 7 Second attempt Class interface –bool hasOtherUser(); –String* getOtherUser(); What is the mental process? –Define the other user as a concept Either there is one or there is not –The user of this object does not need to be aware of the storage conventions He works with the concept of ”another user" rather than with a stored value (attributes not disclosed) WebConnection bool hasOtherUser(); String* getOtherUser();
8
Karlstad University Dept. of Computer Science Semla 2 page 8 Contract for the second attempt Precondition for hasOtherUser: –true Postcondition for hasOtherUser: –result = true if there is another user defined, else false What is the gain in abstraction? –The fact that there may or may not be an "other user" becomes a property of the class, not a value of a variable –No knowledge of the variable is needed to get the answer –The answer may in fact be evaluated WebConnection bool hasOtherUser(); String* getOtherUser();
9
Karlstad University Dept. of Computer Science Semla 2 page 9 Consequences of the second attempt Possible calling style if (connection->hasOtherUser()) { theOther = connection->getOtherUser(); doSomethingWith(theOther); } else handleTheNoUserCase(); WebConnection bool hasOtherUser(); String* getOtherUser();
10
Karlstad University Dept. of Computer Science Semla 2 page 10 What is the difference? Your module may be exposed to clients that are –yourself –trusted friends –colleagues within the same project –colleagues from other projects –external customers –API programmers –end users, through a user interface Who do you trust? –To whom do you expose a strong or a weak contract? A correct call is always your client’s responsibility –Even weak contracts fall back on the client –Error messages or exceptions must be caught by the client or user.
11
Karlstad University Dept. of Computer Science Semla 2 page 11 The implication of a contract Precondition A precondition is a Boolean expression that must be true when an operation is called. A precondition is not a guard condition; it is a condition that must be true, not a way to optionally execute an operation. The condition is supposed to be true, and anything else is a programming error. It can be useful to test the precondition at the beginning of the operation for reliability, but this is in the nature of debugging a program. Postcondition A postcondition is a Boolean expression that must be true after the execution of an operation completes. It is an assertion, not an executable statement. The condition is supposed to be true, and anything else is a programming error. It can be useful to test the postcondition after the operation, but this is in the nature of debugging a program.
12
Karlstad University Dept. of Computer Science Semla 2 page 12 The implication of a contract (cont’d) Precondition It is the responsibility of the caller to satisfy the condition. It is not a condition that the receiver should have to check. If the condition is not satisfied, no statement can be made about the integrity of the operation of the system. It is liable to utter failure. Postcondition A postcondition imposes a constraint on the implementor of an operation. Source: Rumbaugh, J., Jacobson, I., Booch, G., The UML Reference Manual, Addison Wesley 1999. Parts of the descriptions have been rearranged to highlight similarities and differences.
13
Karlstad University Dept. of Computer Science Semla 2 page 13 When to use strong contracts? Strong contracts is the default mode Use strong contracts when the client is yourself, whom you trust to write good code the the client is a programmer. –That is, whenever the client is a programmer, she/he can be trusted.
14
Karlstad University Dept. of Computer Science Semla 2 page 14 When to use weak contracts? Weak contracts are the exception Use weak contracts for –end user communication (end users) cases where the end user may interfere user interfaces –unforeseeable internal problems hardware problems communications problems –very costly preconditions matrix inversion checking the precondition = doing the job –concurrent processing another thread may break the precondition after the check
15
Karlstad University Dept. of Computer Science Semla 2 page 15 Example Array A class Array is an abstraction of a C int array –an Array instance has a fixed lower index: 0 –an Array instance has a fixed number of elements defined at creation time Constructor: –Array() Precondition: true Postcondition: number of elements = 0 –Array(int n) Precondition: n >= 0 Postcondition: number of elements = n, all elements = 0
16
Karlstad University Dept. of Computer Science Semla 2 page 16 Example Array Properties for Array a –int size() Precondition: true (*) Postcondition: the number of elements in the array is returned Data access and assignment for Array a –a[i] Precondition: i >= 0 and i < a.size() Postcondition: a reference to the element at index ’i’ has been returned Usage of data access and assignment of Array a –Data access n = a[i] –Data assignment a[i] = n (*) The precondition true will not be written out. No precondition = true
17
Karlstad University Dept. of Computer Science Semla 2 page 17 Implementation details for Array Assume the data storage is through a pointer –int *_data; Constructor Array(int n) { // assign storage for i elements of int _data = new int[n]; // initialize the elements to zero for (int i = 0; i < n; i++) _data[i] = 0;} No promises are given for illegal values of n –Let the program crash if it wants. It is the client’s problem. –Make the program crash if you want. Constructor Array(int n) { ASSERT (n >= 0)// validate the precondition // the rest of the constructor
18
Karlstad University Dept. of Computer Science Semla 2 page 18 More implementation details for Array Data access int &operator[](int i) { return _data[i]; } No promises are given for illegal values of i –Let the program crash if it wants. It is the client’s problem –Make the program crash if you want int &operator[](int i) { ASSERT ( (i >= 0) && (i < size()) ) return _data[i]; } –Any function called in the ASSERT must be side effect free
19
Improved software quality through semantic descriptions (Skutt) Karlstad University Dept. of Computer Science 2000-05-09 Invariants
20
Karlstad University Dept. of Computer Science Semla 2 page 20 An invariant is ”always” true Established at creation Maintained by all functions Every function implementation can always assume that the invariant is true Every function implementation should always restore the invariant {I} means that the invariant is valid here Establish invariant > operation() Maintain invariant operation() Maintain invariant {I}
21
Karlstad University Dept. of Computer Science Semla 2 page 21 Invariant example Document invariants as comments class WebConnection { String *otherUserName;// NULL if no user, else his name } Complicated invariants are documented separately class WebConnection { String *otherUserName; // Invariant: // otherUserName == NULL if no "other user" is defined //*otherUserName == "" means "user exists but not known" }
22
Karlstad University Dept. of Computer Science Semla 2 page 22 Invariants often document implementation issues The exact interpretation of and conventions for otherUserName is a private concern –special values should not be known to the environment –the “no user” case should be conveyed to the client through an abstraction boolean hasUser()
23
Karlstad University Dept. of Computer Science Semla 2 page 23 Are the invariants visible from the outside? The external aspects should be limited to those that are meaningful to the concept described and not tied to the implementation But sometimes there are invariant conditions that are given by the concept defined and independent of the implementation The size of an array is always >= 0 –So the size in the constructor must be >= 0 to establish the invariant –Does not depend on the implementation The size of a list is always >= 0 –So the size must be >= 1 before a removal not to break the invariant Since a removal reduces the size by one which would make a negative size if not >= 1 before The implementation may add more invariants not visible outside –size == 0 _first == NULL
24
Karlstad University Dept. of Computer Science Semla 2 page 24 External and internal invariants External invariant –Type invariant –Abstraction invariant –Relates to the abstraction itself, regardless of implementation –Visible from outside –Documented with the external documentation (API) Internal invariant –Implementation invariant –Tied to the specific implementation –Not visible from outside –Documented in the code only LinkedList add(element) find(element)... LinkedNode 0..1 _ first client External invariant: size() > 0 Internal invariant: _first == NULL the list is empty _first != NULL => _first points to the first element in the list
25
Karlstad University Dept. of Computer Science Semla 2 page 25 An implementation invariant: linked list implementation A linked list head Invariant –_first == NULL or _first points to the first element in the list –_first == NULL the list is empty Implementation –constructor: establish invariant LinkedList() {_first = NULL;} // an empty list LinkedList add(element) find(element)... LinkedNode 0..1 –add: assume invariant at entry, restore invariant before exit add(element) { LinkedNode newNode = new LinkedNode(element); if (_first == NULL) _first = newNode; else appendAtEnd(newNode); } _ first client
26
Karlstad University Dept. of Computer Science Semla 2 page 26 Another implementation invariant: array implementation Data declaration –int *_data; –int _size; Invariant: –_data != NULL –more? Constructor Array(int n) –_data = new int[n]; Array int _size Array(int) operator[](int)... client 1 Possible alternative invariant –if _size > 0 then _data != NULL else _data == NULL Consequences for the constructor Array(int n) –if (n == 0) _data = NULL; else _data = new int[n]; Consequences for the indexing operator operator[](int i) –none, the precondition assures a correct call _ data int
27
Karlstad University Dept. of Computer Science Semla 2 page 27 Relations between invariants and pre- and postcontidions As a main rule, the invariant is always part of all preconditions and all postconditions –follows from the definitions Part of the invariant is normally implementation oriented and the pre- and postconditions client oriented –There is one set of pre- and postcondition of interest to the client –There is another set of pre- and postcondition of interest for the implementation –the precondition for the implementation = the precondition exported to the clients + the (external) invariant for the abstraction + the (internal) invariant for the implementation –Similarly for the postcondition
28
Karlstad University Dept. of Computer Science Semla 2 page 28 Implement a queue using an array Data declaration –int *_data; –int _size; Invariant –_data != NULL –_size = number of used elements –the first element is at _data[0] Stack int _size Array(int) operator[](int)... int 1 Consequence –Positions 0 through size()-1 hold data Removal: remove() –Precondition: size() > 0 –Implementation {for (int i = 1; i < _size; i++) _data[i-1] = _data[i]; // maintains implementation invariant _size = _size - 1;} _ data client
29
Karlstad University Dept. of Computer Science Semla 2 page 29 Are invariants useful? An invariant should be stated explicitly Useful for the design –Forces you to think over what you really want, since you should write it down Useful to maintain consistency over time –Documents your decisions –Helps you not change your mind halfway through Useful to support the implementation –Tells you what you can rely on and what you need to accomplish in addition to the public preconditions and postconditions Useful for error detection –Tests may be activated on the invariants to detect when :-) they are broken
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.