| CS 535: Object-Oriented Programming & Design |
|
|---|
Fall Semester, 1997
Doc 5, Conceptual OO Definition
To Lecture Notes Index
San Diego State University -- This page last updated 17-Sep-97
Contents of Doc 5, Conceptual OO Definition
- Reference
- Conceptual Level Definition
- Some Typical Beginner Mistakes
Object-Oriented Design Heuristics, Riel, Addison-Wesley, 1996
Heuristics 2.1, 2.8, 2.9, 3.3
of OO
- "Extracting the essential details about an item or group of items, while
ignoring the unessential details."
-
- Edward Berard
- What is it?
-
- Can you describe it with a simple sentence?
-
- It contains data and operations (behavior)on the data
- Enclosing all parts of an abstraction within a container
- Hiding parts of the abstraction
- Abstractions arranged in order of rank or level
Stack Example
Definition
- "A stack is a linear list for which all insertions and deletions are made
at one end of the list"
Operations
- pop, push, isEmpty, isFull
Stack Class
class Stack[1] {
private float[] elements;
private int topOfStack = -1;
public Stack( int stackSize ) {
elements = new float[ stackSize ];
}
public void push( float item ) {
elements[ ++topOfStack ] = item;
}
public float pop() {
return elements[ topOfStack-- ];
}
public boolean isEmpty() {
if ( topOfStack < 0 ) return true;
else return false;
}
public boolean isFull() {
if ( topOfStack >= elements.length ) return true;
else return false;
}
}
Using the Stack
Stack me = new Stack( 20 );
me.push( 5 );
me.push( 12 );
System.out.println( me.pop() );
System.out.println( me.pop() );
A Struct Version
struct Stack
{
float stack[100];
int topOfStack;
};
void push(Stack& it, int item)
{
it.stack[(it.topOfStack)++] = item;
}
float pop(Stack& it)
{
return it.stack[--(it.topOfStack)];
}
main()
{
Stack tryThisOut;
Stack yours, mine;
tryThisOut.topOfStack = 0;
yours.topOfStack = 0;
push( tryThisOut, 5.0 );
push( yours, 3.3 );
push( tryThisOut, 9.9 );
cout << pop( tryThisOut ) << endl;
}
Problems with the Struct Version
Encapsulation
- Data is encapsulated
-
- Operations are not encapsulated with data
-
- The boundaries of what it is become fuzzy
On larger abstractions it decreases:
- Composability
- Understandability
- Continuity
Information hiding
- Data is not hidden
-
- Data is not safe!
Stack troubleAhead;
troubleAhead.topOfStack = 13;
troubleAhead.stack[ 8 ] = 29;
Struct-like Class
class StackData
{
public float[] elements = new float[100];
public int topOfStack = 0;
}
class Test
{
static void push(Stack it, int item)
{
it.stack[ ( it.topOfStack )++ ] = item;
}
static float pop(Stack it)
{
return it.stack[--(it.topOfStack)];
}
public void static main( String[] args)
{
Stack yours, mine;
push( yours, 3.3 );
push( mine, 9.9);
}
Some Typical Beginner Mistakes
The Long Way Struct-like Class
class StackData
{
private float[] elements = new float[100];
private int topOfStack = -1;
public int getTopOfStack()
{
return topOfStack;
}
public void setTopOfStack( int newTop )
{
topOfStack = newTop;
}
public float getElement( int elementIndex )
{
return elements[ elementIndex ];
}
public void getElement( int elementIndex, float element )
{
elements[ elementIndex ] = element;
}
}
Some Typical Beginner Mistakes
Mixing IO and an Abstraction
class Stack {
private float[] elements = new float[ 100 ];
private int topOfStack = -1;
public void push( )
{
float item = Console.readFloat( "Type a float to push");
elements[ ++topOfStack ] = item;
}
public void pop()
{
Console.println( "Top stack item: " +
elements[topOfStack--];
}
}
class Test
{
public void static main( String[] args)
{
Stack yours ohNo = new Stack();
ohNo.push( );
ohNo.push( );
ohNo.pop( );
}
Design Heuristics
- All data should be hidden within its class
- A class should capture one and only one key abstraction
- Keep related data and behavior in one place
- Beware of classes that have many accessor methods in their public
interface. This implies data and behavior are not in one place
Applying these heuristics to your classes will go a long way to help you avoid
typical beginner mistakes in designing classes
RPN Calculator
Postfix (Reverse) Polish Notation
- ( 3 + 9 - 13 ) * 6 + 2
-
- becomes
-
- 3 9 + 13 - 6 * 2 +
Evaluating RPN
- read next token
-
- if token is operand push on stack
-
- if token is operator
- pop two items off the stack
-
- apply operator to the items from stack
-
- push result on stack
-
- repeat until no more tokens
-
- result is on the top of the stack
CalculatorEngine
class CalculatorEngine
{
private Stack operands = new Stack( 100 );
public float evaluate( String expression )
{
StringTokenizer tokenList =
new StringTokenizer( expression );
while ( tokenList.hasMoreTokens() )
processToken( tokenList.nextToken() );
return operands.pop();
}
private void processToken( String token )
{
if ( token.equals( "+" ) )
operands.push( operands.pop() + operands.pop() );
else if ( token.equals( "-" ) )
operands.push( operands.pop() - operands.pop() );
else if ( token.equals( "/" ) )
operands.push( operands.pop() / operands.pop() );
else if ( token.equals( "*" ) )
operands.push( operands.pop() * operands.pop() );
else
operands.push( stringToFloat( token ) );
}
private float stringToFloat( String number )
{
return Float.valueOf( number ).floatValue();
}
}
Calculator Application
class CalculatorGUI
{
CalculatorEngine rpnEvaluator;
public CalculatorGUI( CalculatorEngine myComputeEngine )
{
rpnEvaluator = myComputeEngine;
// code to build the gui interface removed
}
// code to make gui run removed
}
Driver Program for Calculator
public static void main( String[] arguments )
{
CalculatorGUI fourBanger;
fourBanger = new CalculatorGUI( new CalculatorEngine() );
}
Computation as Simulation
Procedure
programming consists of procedures acting on data
Object-oriented programming consists of objects interacting
Main() creates web of objects and starts them interacting

The OO Process
Step One
- Identify the data and the operations on the data
-
- These start to form the classes
Step Two
- Determine how classes interact
Step N
- Create program on top of the classes
visitors since 17-Sep-97