150 likes | 239 Views
Specifying Object Interfaces. Major tasks in this stage: --are there any missing attributes or operations? --how can we reduce coupling, make interface simple? * what operations are public/private/protected? * what are input parameters of each operation?
E N D
Major tasks in this stage: --are there any missing attributes or operations? --how can we reduce coupling, make interface simple? * what operations are public/private/protected? * what are input parameters of each operation? * what is the return type of each operation? --what “contracts” are there? (pre and post conditions, e.g.)
Developers participating in class specification: • * implementer—designs internal data structures and code for the class • * user—will use the class as an application—must know boundary (interface specification) for the client class they are developing • * extender—develops specialized version of the class—interface specifications provide constraints to this developer
“contracts”: useful in white box and black box testing, include preconditions, postconditions, and invariants (loop or class, e.g.). Example: how do you ensure --there is no division by zero? --array bounds are not exceeded? --I/O error does not cause system crash? --faulty / missing component does not cause system crash? Also important in formal methods specifications Preconditions, postconditions, invariants
precondition: logical condition that a caller of an operation guarantees before making the call postcondition: logical condition that an operation guarantees upon completion invariant: logical condition that is preserved by transformations example: loop invariant is preserved by the transformations effected by the loop instructions Preconditions, postconditions, invariants--definitions
example: what would be preconditions for common stack operations? What would be postconditions? Push: Pop: Isempty?: Top: what about a queue? What about division? (precondition; postcondition—e.g., type) Example--stacks, queues, division
example: does this program compute an for n > 0? Algorithm strategy? float pow(float a, int n) { float r = 1; while (n > 0) { {if (n%2 == 0) {a = a*a;n=n/2;} else {r=r*a; n=n-1;} } } return r; } "proof" using an invariant that this program is correct: let ain , nin be inputs; invariant: r x an = ain ** nin proof: 1. Invariant holds before entering loop first time 2. Invariant holds after iteration i if it held at iteration i-1 3. So, by induction, invariant is true for n > 0 3. Now, if loop terminates, n = 0, so we program does compute an Loop invariant
example: class invariant is preserved by all class operations e.g., the size of an array is always >= 0 interface invariants: for public sections (users) implementation invariants: for class implementations (designers, coders) Other invariants
example: suppose we have a bounded stack of floating point numbers interface invariant: after a push, the stack is no longer empty s.push(x) => not (s.empty) if the stack is not full and we push an element on the stack, then calling pop returns that element: not(s.full) and s.push(x); y=s.pop => x = y these make no reference to the particular implementation Invariants--examples
Implementation invariant: example: if we implement the stack as a bounded array then an invariant is that the stack pointer is within the array bounds using invariants in program: c++: assert c++ , java: error checking--(e.g., try, catch) note: including checking increases program length, decreases efficiency Invariants--examples (cont.)
Expressing constraints: Can use natural language or a special language such as OCL (Object Constraint Language) Constraint is a boolean expression, returns value true or false Constraint can be: --attached to an entry in the CRC card if desired (example: figure 9.4)—leads to cluttered documents --specified by keyword context
Examples from text (this form or syntax in figure 9-5, page 360 should be used in object comments in project): context Tournament inv: self.getMaxNumPlayers( ) > 0 context Tournament::acceptPlayer(p:Player) pre: !is PlayerAccepted(p) context Tournament::acceptPlayer(p:Player) pre: getNumPlayers( ) < getmaxNumPlayers( ) context Tournament::acceptPlayer(p:Player) post: isPlayerAccepted(p)
Useful OCL syntax: Collections of objects: distinguishes among sets, sequences, bags --set: for a single association; ex: {3, 9, 7, 5} --sequence: used for navigating a single ordered association ex: {a1, a2} --bag: may contain the same object multiple times (differs from set) ex: {3, 9, 7, 5, 3} Useful operations on collections: Size includes(object)—member select(expression)—members which satisfy given condition union(collection) intersection(collection) asSet(collection)—returns the set of members of the collection Quantifiers: ∀-for all; ∃-exists We will revisit these concepts when we discuss formal methods
Object design—steps: ---Identify missing attributes and operations ---specify types, signatures (e.g. is a collection ordered or not?), and visibility of each attribute and operation --specify pre and post conditions --specify invariants --note any inherited contracts --document the process in the Object Design Document --assign development responsibilities to developer team