Sei sulla pagina 1di 29

Technical University of Cluj-Napoca

Computer Science Department

Object Oriented
Programming Techniques

Class Level Design and


Implementation
Part 1

Professor Ioan Salomie


Spring 2010
Ioan Salomie - Programming Techniques

Objective
Presenting

the main techniques and


paradigms that govern class design

Ioan Salomie - Programming Techniques

Types of classes
Public and Auxiliary
Public

classes

public access qualifier


general use
file - class name constraint
Auxiliary

(helper) classes

Should not be declared as public


Supports one public class
reside in the same file

Supports multiple public classes


Defined in the same package
Separate definition file
Problems with inheritance when a class
from another package inherits a class
from the current package
Ioan Salomie - Programming Techniques

Type of classes
Top level and inner classes
Top

level classes

Top level, members of a package


It is an error to define a top level class
as static

classes defined within a


top-level class

Inner

Anonymous
Local
Member
Nested top-level

Ioan Salomie - Programming Techniques

Type of classes
Top level and inner classes
Inner

classes Anonymous

Declared and instantiated within the


same statement
They do not have names, and they can
be instantiated only once
An anonymous class cannot be declared
static
Example
okButton.addActionListener( new ActionListener(){
public void actionPerformed(ActionEvent e){
dispose();
}
});
Ioan Salomie - Programming Techniques

Type of classes
Top level and inner classes
classes Local
Same as local variables,
Inner

They're created and used inside a block


Once you declare a class within a block,
it can be instantiated as many times as
you wish within that block
Like local variables, local classes are
not allowed to be declared public,
protected, private, or static

Ioan Salomie - Programming Techniques

Type of classes
Top level and inner classes
classes Local
Example (from JavaWorld, 08/99)
Inner

//some code block .......{


class ListListener implements ItemListener {
List list;
public ListListener(List l) {
list = l;
}
public void itemStateChanged(ItemEvent e) {
String s = l.getItemSelected();
doSomething(s);
}
}
List list1 = new List();
List list2 = new List();
list1.addItemListener(new ListListener(list1));
list2.addItemListener(new ListListener(list2));
}
Ioan Salomie - Programming Techniques

Type of classes
Top level and inner classes
classes Member
the body of a class
Can be used anywhere within the body of
the containing class
You declare member classes when you
want to use variables and methods of the
containing class without explicit
delegation
The member class is the only class that
you can declare static
Inner

Defined within

Ioan Salomie - Programming Techniques

Type of classes
Top level and inner classes
classes Member (2)
Non static inner member classes
Inner

When you declare a member class, you can


instantiate that member class only within the
context of an object of the outer class in which
this member class is declared
Static

inner member classes

If you want to remove the above restriction,


you declare the member class a static class
When you declare a member class with a
static modifier, it becomes a nested top-level
class and can be used as a normal top-level
class as explained in the next slide

Ioan Salomie - Programming Techniques

Type of classes
Top level and inner classes
classes Nested top-level
nested top-level class is a member
classes with a static modifier
A nested top-level class is just like any
other top-level class except that it is
declared within another class or interface
Nested top-level classes are typically used
as a convenient way to group related
classes without creating a new package
Inner
A

Note.

The meaning of static keyword


associated to a class declaration is not the
same with its meaning when associated to
a variable or a method declaration

Ioan Salomie - Programming Techniques

10

Example
public interface List {
// mutators
public void addElement(Object le, int i);
public void addFirst(Object le);
public void addLast(Object le);
public Object remove(int i);
public Object removeFirst();
public Object removeLast();
// getters (accessors)
public Object getFirst();
public Object getLast();
public Object getElement(int i);
public int getSize();
// test
public boolean isEmpty();
}
Ioan Salomie - Programming Techniques

11

Example
Class

DLlist

doubly linked list


implements the interface List
public class in DLlist.java
Class

DLnode

list node
auxiliary class
should not be exposed to the clients
resides in the same file as DLlist

Ioan Salomie - Programming Techniques

12

Example
Class DLnode - alternative 1
public class DLlist implements List {
protected DLnode head, tail;
protected int howMany;
// implementations
}
class DLnode {
Object element;
DLnode next, prev;
}
DLnode class
accessible to all package classes
not accessible to any DLlist subclass, not in
the same package
Ioan Salomie - Programming Techniques

13

Example
Class DLnode - alternative 2
public class DLlist implements List {
protected DLnode head, tail;
protected int howMany;
static protected class DLnode {
Object element;
DLnode next, prev;
}
// implementations
}
DLnode class
accessible to all DLlist subclasses

Ioan Salomie - Programming Techniques

14

Main class design


guidelines (1)
Instance

variables (or fields)

Avoid public fields


see example Point and PolarPoint

Field mutators or setters ???


setAttr()
see example Point and PolarPoint

Getters
getAttr()

Return type boolean


isAttr()
Naming

fields

code conventions
semantic names
the power of names
Ioan Salomie - Programming Techniques

15

Example
public class Point {
protected double x, y;
// constructor, getX, getY, setX, setY
}
public class PolarPoint extends Point {
protected double r, a;
//
}
Invariant constraint
links the two classes:

x = r * Math.cos(a)
y = r * Math.sin(a)
What if r and a were public???
PolarPoint pp = new PolarPoint();
pp.r = 20.9; // => inconsistent state
Ioan Salomie - Programming Techniques

16

Example
Keeping

consistent state

Use mutators setRadius() and


setAngle()
Use housekeeping methods
rectangularToPolar() and
polarToRectangular()
Override methods setX and setY in
PolarPoint class
Example

(pp remains consistent)

PolarPoint pp = new PolarPoint();


pp.setRadius(21.9);

Ioan Salomie - Programming Techniques

17

Class PolarPoint
public class PolarPoint extends Point {
protected double r, a;
public PolarPoint() { }
public PolarPoint(final double r, final double a) {
this.r = r; this.a = a;
polarToRectangular();
}
public double getRadius() { return r; }
public double getAngle() { return a; }
public void setRadius(final double r) {
this.r = r;
polarToRectangular()
}
public void setAngle(final double a) {
this.a = a;
polarToRectangular()
}
// => (next slide)

Ioan Salomie - Programming Techniques

18

Class PolarPoint
public void setX(final double x) {
this.x = x;
rectangularToPolar()
}
public void setY(final double y) {
this.y = y;
rectangularToPolar()
}
protected void polarToRectangular() {
x = r * Math.cos(a); y = r * Math.sin(a);
}
protected void rectangularToPolar() {
r = Math.sqrt(x * x + y * y);
a = Math.atan2(y, x);
}
} // end class

Ioan Salomie - Programming Techniques

19

Design Guidelines (2)


1. Completeness of the public interface
Class public methods should provide
full and convenient access to the
functionality of the class

2. Separate interface from


implementation
When the class functionality can be
implemented in different ways =>
separate the interface from the
implementation

Ioan Salomie - Programming Techniques

20

Separate interface from


implementation
Example

List implementation
Ordered collection - accessed through an
index.
The size of the list can grow as needed

Implementation alternatives
linked list
dynamically resizable array

Ioan Salomie - Programming Techniques

21

Separate interface from


implementation
Advantages

hidden details
changes in implementation
Interface

described by List
Implementations

LinkedList
public class LinkedList implements List {
// implementation body
}
DynamicArray
public class DynamicArray implements List {
// implementation body
}

Ioan Salomie - Programming Techniques

22

Separate interface from implementation


Java vs. C++
Java
C++

header file
implementation file
Differences

C++
header file and implementation file are
two parts of the same class
header file contains interface and some
implementation
attributes
in-line methods

Java
interface and implementation class are
two different entities
the interface - no implementation
all implementation is included in the class
Ioan Salomie - Programming Techniques

23

Documenting the source code


Documentation

(doc) comments
utility
http://java.sun.com/j2se/javadoc/
Formatted comments can be added to
javadoc

classes
methods
fields
javadoc

is invoked to generate
documentation
doc comment
feature description
list of tags

Ioan Salomie - Programming Techniques

24

Documenting the source code


Common tags

@author
multiple tags allowed
feature author (s)

@version

@since

@param

current version
when or in which version the feature appeared
associated with methods, multiple tags
meaning
range values

@return
meaning
possible values or range

@see

@throws

associated documentation
unhandled exception that might be thrown by method

Ioan Salomie - Programming Techniques

25

Example
/**
* Class Circle defines the abstraction Circle
* A circle object is defined by its center
* point and radius
* @author xxxxx
* @version 0.1 09/04/2009
* @ since JDK 5.0
*/
public class Circle extends Shape2D {
//
}
//**
* get the i-th element of the list
* @param i Position of the element
* @return
Returns the i-th element of the list
* @see
# add(Object le, int i)
*/
public Object getElement(int i) {
//
}

Ioan Salomie - Programming Techniques

26

Contracts and invariants


Contracts of methods
Method

contract

Specification of method behavior


(method service specification)
Contracts of methods
usually informally specified or
left unspecified
major problems in software development

Ioan Salomie - Programming Techniques

27

Contracts and invariants


Contracts of methods
Potential

problems of informal
specifications of contracts
incomplete on some behavior aspects
ambiguity and multiple interpretations
contradictions with other contracts

Advantages

of formally specified

contracts
precision and unambiguousness
run time checking
catch contract violations by the
implementations as well as
misused of the services by the clients

facilitates reasoning about the behavior


of implementation and clients
Ioan Salomie - Programming Techniques

28

Contracts and invariants


Contracts of methods
Specification

languages - support
formally specifying the complete
behavior of software systems
needs mathematical skills
algebraic specification: Larch
model based specification: Z and
VDM
high costs => recommended for highly
critical applications
limited use can be easy and very costeffective

Ioan Salomie - Programming Techniques

29

Contracts and invariants


Contracts of methods
Main

contract goals

Ensures constraints on services are met


Ensures maintaining of certain conditions on
implementation
Contract specification

method pre-conditions
method post-conditions
Pre-condition

boolean expression
Must hold when the method is invoked
Otherwise, exception is thrown

Post-condition

boolean expression
holds when the method invocation returns

Ioan Salomie - Programming Techniques

30

Contracts and invariants


Contracts of methods
/**
* @ pre precondition as boolean expr
* @ post postcondition as boolean expr
public void m1() { }
Notes.
- @pre and @post tags are not supported by Javadoc tool
- There are 3rd party tools supporting these tags

pre and post conditions may occur multiple


times

pre and post specifications

conjunction of all boolean conditions


Java expression syntax plus the following (for
increasing expresive-ness)
@result
variable holding the return value of the method

@nochange
boolean expression saying that the state of the object is
not changed by the method

boolean operators
=> (logical implication)
<=> (logical equivalence)
Ioan Salomie - Programming Techniques

31

Contracts on Accessors
Examples
/**
* returns the # of list items
* @pre true
* @post @nochange
*/
public int getSize();
/**
* returns true if and only if the list is empty
* @pre true
* @post @result <=> getSize() > 0
* @post @nochange
*/
public boolean isEmpty();

Ioan Salomie - Programming Techniques

32

Examples
@pre

true

Precondition is always satisfied


The methods can be invoked any time
@post

@nochange

The method is not changing the state


of the object

Ioan Salomie - Programming Techniques

33

Examples
/**
* returns the i-the list item
* @pre i >= 0 && i < getSize()
* @post @nochange
*/
public Object getElement(int i);
For

a more detailed and precise


functionality specification
Larch, Z or VDM

Ioan Salomie - Programming Techniques

34

Examples
/**
* returns the first list item
* @pre !isEmpty()
* @post @result == getElement(0)
* @post @nochange
*/
public Object getFirst();
/**
* returns the last list item
* @pre !isEmpty()
* @post @result == getElement(getSize() - 1)
* @post @nochange
*/
public Object getLast();
Ioan Salomie - Programming Techniques

35

Contracts on mutators
Object

state

before mutator invocation


after mutator invocation
Default

on post expressions

object state after method execution

Ioan Salomie - Programming Techniques

36

Contracts on collections
Quantified expressions
Universally

quantified expression

predicate holds on every object in the


collection
Existentially quantified expression

predicate holds on at least one object in the


collection
Specification extensions

Universally quantified expression


@forall x : Range @ Expression

Existentially quantified expression


@exists x : Range @ Expression

Meaning
x is variable name,
Range expression, specifies the collection
Expression, boolean expression
Ioan Salomie - Programming Techniques

37

Contracts on collections
Range

expressions

[m .. n]
int range
m, n integer expressions

Expression
Expression must evaluate to Collection,
Enumerator or Iterator objects
Defines a range in the collection contains
all objects in the collection, enumeration
or iterator

ClassName
Defines a range consisting of all the
instances of a class

Ioan Salomie - Programming Techniques

38

Example
Method

addElement pre and post


conditions

/**
* Adds a new element to the list on position i
* @pre el != null && i>=0 && i <= getSize()
* @post getSize() == getSize()@pre + 1
* @post @forall k : [0 .. getSize() -1 ] @
*
(k <i ==> getElement(k)@pre == getElement(k)) &&
*
(k == i ==> el@pre == getElement(k) &&
*
(k > i ==> getElement(k-1)@pre == element(k)
*/
public void addElement (Object el, int i);

Ioan Salomie - Programming Techniques

39

Example
/**
* Adds a new element at the head of the list
* @pre el != null
* @post getSize() == getSize()@pre + 1
* @post el@pre == getElement(0)
* @post @forall k : [0 .. getSize() -1 ] @
*
(getElement(k-1)@pre == getElement(k))
*/
public void addFirst (Object el);
/**
* Adds a new element at the end of the list
* @pre el != null
* @post getSize() == getSize()@pre + 1
* @post el@pre == getElement(getSize() - 1)
* @post @forall k : [0 .. getSize() -2 ] @
*
(getElement(k)@pre == getElement(k))
*/
public void addLast (Object el);

Ioan Salomie - Programming Techniques

40

Example
Method

remove

/**
* Remove the element at the i-th position
* @pre getSize() > 0
* @pre i >= 0 && i < getSize()
* @post @result = getElement(i)@pre
* @post getSize() == getSize()@pre - 1
* @post @forall k : [0 .. getSize() -1 ] @
*
(k <i ==> getElement(k)@pre == getElement(k)) &&
*
(k >= i ==> getElement(k+1)@pre == element(k)
*/
public void remove (int i);

Ioan Salomie - Programming Techniques

41

Example
/**
* Remove the element at the list head
* @pre getSize() > 0
* @post @result = getElement(0)@pre
* @post @forall k : [1 .. getSize() -1 ] @
*
getElement(k+1)@pre == element(k)
*/
public void removeFirst(int i);
/**
* Remove the element at the end
* @pre getSize() > 0
* @post @result = getElement(getSize() - 1)@pre
* @post @forall k : [0 .. getSize() -1 ] @
*
getElement(k)@pre == element(k)
*/
public void removeLast (int i);

Ioan Salomie - Programming Techniques

42

Contracts and
implementations
All

classes that implement List


should fulfill the contract
stipulations
Pre and post conditions of the
interface methods =>
Pre and post conditions of the class
methods that implement the interface

Ioan Salomie - Programming Techniques

43

Class invariants
Object

state

Stable
initialized, but not being manipulated

Transient
the object is being manipulated, i.e. a
method is executing on the object
Invariants

of a class

Formally specified condition


always holds on any object of the class
whenever it is in a stable state

Well-formed state

Ioan Salomie - Programming Techniques

44

Example
DLlist

- implementation of the List


interface
Implementation main features
If the list is empty =>
head should be null and
tail should be null

If the list is not empty =>


head points to the first list element and
tail points to the last list element

howMany value should be equal to # of


nodes reachable by following the next link
from the list head

Ioan Salomie - Programming Techniques

45

Example (cont.)
Implementation

main features

(cont.)
For each node reachable from head
prev field of its succeeding node should point
to itself
next field of its preceding node should point to
itself

The prev of the first node and the next of


the last node is null
DLlist

representation is well formed

if all the above conditions hold whenever


a linked list object is in a stable state
The

conditions are invariants of the


DLlist used to implement the List
interface

Ioan Salomie - Programming Techniques

46

Auxiliary method for


DLL invariants
protected boolean isWellFormed {
int n = 0;
for(DLnode p = head; p != null; p = p.next) {
n++;
if(p.prev != null) {
if(p.prev.next != p) return false;
}
else {
if(head != p) return false;
}
if(p.next != null) {
if(p.next.prev != p) return false;
} else {
if(tail != p) return false;
}
}
return n == howMany();
}
Ioan Salomie - Programming Techniques

47

Documenting the invariants


New

tag

@invariant booleanExpression

/**
* @invariant isWellFormed()
*/
@invariant tag can occur many times
AND of all boolean expressions
Entities used in invariants
implication operator
equivalence operator
quantified expressions
Invariants

deal with the objects at a given


moment
Class programmer must ensure
all public methods preserve the invariants
Ioan Salomie - Programming Techniques

48

DLL invariant
/**
* @invariant isWellFormed()
*/
public class LinkedList implements List() {
// implementation
protected boolean isWellFormed() {
// invariant implementation
}
protected DLnode head, tail;
protected int count;
static protected class DLnode {
Object item;
DLnode next, previous;
}
}
- Class implementer must ensure that all public methods
preserve the invariants

Ioan Salomie - Programming Techniques

49

Design guideline (3)


The

invocation of any method, in


any order should always result in a
well-formed state
This is achieved if the following
implementation obligations hold (for
a given class)
For each public class constructor
The invariants must be post-condition of
the constructor or implied by its postcondition

For each public method of the class


invariants can be

assumed as method preconditions and


must be method post-condition or implied by
post-condition

Ioan Salomie - Programming Techniques

50

Assertions
Run-time checking

pre and post conditions of methods and


class invariants
Assertion

boolean condition at a given program


location
Condition should be true whenever the
execution flow reaches the assertion location
Java assessment statements (beginning with
JDK 1.4) - check assertions at run time
Syntax:

assert assertionCondition;
assertCondition - boolean expression
if true, assert has no effects
if false, AssertionError exception is thrown
Ioan Salomie - Programming Techniques

51

Assertions
Assertions

rules

Assertions on method preconditions


placed at the entry point of each method

Assertions on method post-conditions


placed at every exit point of each method

Assertions on class invariants


placed at the entry point and at the exit
point of each public method

Ioan Salomie - Programming Techniques

52

Examples
/**
* returns the first list item
* @pre !isEmpty()
* @post @result == getElement(0)
*/
public Object getHead() {
assert !isEmpty();
Object result = (head != null) ?
head.element : null);
assert result == getElement(0);
return result;
}

Ioan Salomie - Programming Techniques

53

Examples
/**
* Adds a new element to the list on position i
* @pre el != null && i>=0 && i <= getSize()
* @post getSize() == getSize()@pre + 1
*/
public void addElement (Object el, int i) {
assert el != null && i >= 0 && i <= getSize();
assert isWellFormed();
int sizePre = getSize();
if(i<= 0) { addFirst(el); }
else if (i >= count) { addLast(el) }
else {
// i >0 && i < count
DLnode n = head;
for(int j = 0; n != null; && j < i-1; j++) { n = n.next; }
DLnode node = new DLnode();
node.element = el node.next = n.next; node.prev = n;
node.next.prev = node; n.next = node;
count ++
}
int sizePost = getSize();
assert sizePost == sizePre + 1;
assert isWellFormed();
}
Ioan Salomie - Programming Techniques

54

Examples
Comments

assertions derived from


pre and post conditions
class invariants are translated into
assertions

Not all post-conditions are asserted


Post-conditions dealing with objects
pre-state are more complicated to be
asserted
Note

Compiling with assertions


JDK 1.4 or higher

Ioan Salomie - Programming Techniques

55

Defensive programming
Objective

Preventing misuse
How

Using assertions derived from the


preconditions of all methods
An assertion failure of a pre-condition
indicates that the client has attempted to
improperly use the service

Indications given by assertions in case


of an error
Help to determine whether the error is
caused by service implementation or
improper service use
Help

in unit testing

assertions derived from post-conditions and


class invariants - useful in unit testing and
implementation debugging
Ioan Salomie - Programming Techniques

56

Design guideline
Each

method should include


assertions
on pre and post conditions
on class invariants

Ioan Salomie - Programming Techniques

57

Design by contract
Relates to

overriding and implementing

interfaces
Overriding subclass methods and
implemented interface methods should honor
the contracts
No

stronger preconditions in the


subclasses
In other words: the subclass methods cannot
be more restrictive than the corresponding
methods of the super-class

No

weaker post-conditions in the


subclasses
In other words: the subclass methods cannot
be do less than the corresponding methods of
the super-class

Ioan Salomie - Programming Techniques

58

Potrebbero piacerti anche