SDSU CS 535 Object-Oriented Programming & Design
Spring Semester, 1999
Basic Heuristics
Previous    Lecture Notes Index    Next    
© 1999, All Rights Reserved, SDSU & Roger Whitney
San Diego State University -- This page last updated 16-Feb-99

Contents of Doc 6, Basic Heuristics


Reference:

Object-Oriented Design Heuristics , Riel, Addison-Wesley, 1996, Heuristics 2.1, 2.8, 2.9, 3.2, 3.3


Doc 6, Basic Heuristics Slide # 2
The Basic Heuristics

2.1 All data should be hidden within its class

3.3 Beware of classes that have many accessor methods defined in their public interfaces. Having many implies that related data and behavior are not being kept in one place

2.9 Keep related data and behavior in one place

2.8 A class should capture one and only one key abstraction

3.1 Distribute system intelligence horizontally as uniformly as possible

3.2 Do not create god classes/objects in your systems

Doc 6, Basic Heuristics Slide # 3

Example 1 - Stack


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


Doc 6, Basic Heuristics Slide # 4
Stack Class
The following Stack class is not a production level class.

class Stack  {
   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;
   }
}

Doc 6, Basic Heuristics Slide # 5
Using the Stack
   Stack me = new Stack( 20 );
   me.push( 5 );
   me.push( 12 );
   System.out.println( me.pop() );
   System.out.println( me.pop() );

Doc 6, Basic Heuristics Slide # 6

Some Typical Beginner Mistakes

Struct-like Class

One can make a class that is just a struct dressed as a class. Remember heuristic 2.1 All data should be hidden within its 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);
}


Doc 6, Basic Heuristics Slide # 7
Some Typical Beginner MistakesThe Long Way Struct-like Class

This example has all fields hidden. But the methods do not support the stack abstraction. The logic of operating the stack is not in the stack class. This means that the topOfStack field can be improperly set by some one outside the class. Remember heuristic 3.3 Beware of classes that have many accessor methods defined in their public interfaces. Having many implies that related data and behavior are not being kept in one place.

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 setElement( int elementIndex, float element ) {
      elements[ elementIndex ] = element;
   }
}

Doc 6, Basic Heuristics Slide # 8

Information Hiding - Physical and Logical

Physical Information Hiding

Physical information hiding is when a class has a field and there are accessor methods, getX and setX, setting and getting the value of the field. It is clear to everyone that there is a field named X in the class. The goal is just to prevent any direct access to X from the outside. The extreme example is a struct converted to a class by adding accessor methods. Physical information hiding provides little or no help in isolating the effects of changes. If the hidden field changes type than one usually ends up changing the accessor methods to reflect the change in type.

Logical Information Hiding

Logical information hiding occurs when the class represents some abstraction. This abstraction can be manipulated independent of its underlying representation. Details are being hidden from the out side world. Examples are integers and stacks. We use integers all the time without knowing any detail on their implementation. Similarly we can use the operations pop and push without knowing how the stack is implemented.

Doc 6, Basic Heuristics Slide # 9

Example 2 - Linked List


What operations do we want on a linked-list?

addFirst( float data )
addLast( float data )
contains( float data )
get( int index)
getFirst()
getLast()
indexOf( float data)
insert( int index, float data)
contains( float data )
removeFirst()
removeLast()
remove( int index)
remove( float data)
removeAll( float data )
size()

How to implement? In C we would use a struct

struct Node
{
   float data;      
   struct Node*  next;
};

then use it to implement the above functions.

Doc 6, Basic Heuristics Slide # 10

First Java Linked List


package MyLinkedList;
public class LinkedList {
   private Node frontOfList = null;
   
   public void addFirst( float data ) {
      Node newNode = new Node();
      newNode.data = data;
      newNode.next = frontOfList;
      frontOfList = newNode;
   }
      
   public String toString() {
      String listAsString = "";
      Node current = frontOfList;
      while (current != null ) {
         listAsString = listAsString + " " + current.data;
         current = current.next;
      }
      return listAsString;
   }
   
   // Other methods deleted
}
class Node {
   float data;
   Node next = null;
}

Doc 6, Basic Heuristics Slide # 11
Using the First Linked List

import MyLinkedList;
public class Test
   {
   public static void main( String args[] ) throws Exception 
      {
      //new ClassMethodView( Test.class );
      LinkedList test = new LinkedList();
      test.addFirst( 1);
      test.addFirst( 2);
      test.addFirst( 3);
      System.out.println( test );
      }
   }
Output
3.0 2.0 1.0
What is Wrong with the Node Class?

Clearly the Node class does what an earlier slide says not to do. So what? Most textbooks will have Node code that looks like the first example. The Java library source code has many instances of linked lists that use this type of Node class. So what is wrong with Node class? Put another way how can it be improved?.

Think about this before going on to the next slide.

Doc 6, Basic Heuristics Slide # 12

Second Node Class


class Node {
   private float data;
   private Node next = null;
   private Node previous = null;
   public Node( float initialData) {
      this( initialData, null, null );
   }
   public Node( float initialData, 
                  Node previousInList, 
                  Node nextInList )   {
      data = initialData;
      next = nextInList;
      previous = previousInList;
      if ( next != null )
         next.previous = this;
      if ( previous != null )
         previous.next = this;
   }
   
   public void append( float data ) { 
      new Node( data, this, next); 
   }
   public void prepend( float data ) { 
      new Node( data, previous, this); 
   }

Doc 6, Basic Heuristics Slide # 13
// Node Continued

   public void remove() {
      if ( previous != null )
         previous.next = next;
      if ( next != null )
         next.previous = previous;
      previous = null;
      next = null;
   }
      
   public Node getNext() { 
      return next; 
   }
   public Node getPrevious() { 
      return previous; 
   }
   public float getData() {
      return data;
   }
   
   public void setData( float newData ) {
      data = newData;
   }
}

Doc 6, Basic Heuristics Slide # 14
Second Linked List
public class LinkedList {
   private Node frontOfList = null;
   private Node endOfList = null;
   
   public void addFirst( float data ) {
      frontOfList = new Node( data, null, frontOfList );
      if (endOfList == null )
         endOfList = frontOfList;
   }
   public void addLast( float data ) {
      endOfList = new Node( data, endOfList, null );
      if (frontOfList == null )
         frontOfList = endOfList;
   }
      
   public float removeFirst( ) {
      Node oldFirst = frontOfList;
      frontOfList = frontOfList.getNext();
      oldFirst.remove();
      return oldFirst.getData();
   }
   public String toString() {
      String listAsString = "";
      Node current = frontOfList;
      while (current != null ) {
         listAsString = listAsString + " " + current.getData();
         current = current.getNext();
      }
      return listAsString;
   }
}

Doc 6, Basic Heuristics Slide # 15
Is the Second List Better?

What is the difference between the first and second Node classes?

Is the second Node better? If so how?

Doc 6, Basic Heuristics Slide # 16
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



Copyright © 1999 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
All rights reserved.

Previous    visitors since 16-Feb-99    Next