Michael Bolin's 6.170 Recitation

This web site is for members of the recitation that I am teaching for 6.170 Spring 2004. The recitation meets Thursday mornings from 10-11am in 26-210. Here you will find recitation notes as well as links to software development tools that I consider important.
Recitation Notes
2/5 Recitation 1
2/12 Recitation 2
2/19 Recitation 3
2/26 Recitation 4
3/4 Recitation 5
Comments on Problem Sets
Problem Set 0
Problem Set 1
Problem Set 3
Things I Recommend
Software You Should Install
Books You Should Own
Web Sites You Should Use

2/19 Recitation 3

Instead of summarizing the recitation notes for today's lecture, I defer to Professor Miller's document: Handout S8: Writing Abstraction Functions & Rep Invariants.

The only nuggets of information that I would like are about checkRep().

  1. When to Call checkRep
  2. How to Call checkRep

1. When to Call checkRep

As you remember, you should call checkRep() when:
  • you exit a constructor
  • you enter a public method
  • you exit a public method
  • you enter an observer method
  • you exit an observer method that has side-effects
Some people seemed to feel that their lives were incomplete because it's not a rule to always call checkRep() before leaving a public observer method, but consider the following accessor method:
public int getX() {
  return x;
}
Where can we put checkRep()? The only way to put checkRep() in here twice would be overkill:
public int getX() {
  checkRep();
  int theX = x;
  checkRep();
  return theX;
}
As you can see, this is a bit silly (and wasteful), so the following is sufficient:
public int getX() {
  checkRep();
  return x;
}

2. How to Call checkRep

When you have a method that can exit from multiple points in the code, it may be difficult to be sure that there is a checkRep that goes with every return statement. The proposed solution to this problem is to use the finally keyword. In Java, finally is used to delimit a block of code that gets executed regardless of the results of the try block that precedes it. Thus, instead of this method that has checkRep in five places:
public int compareTo(Object obj) {
  checkRep();
  if (!(obj instanceof Card)) {
    if (obj == null); {
      checkRep();
      throw new NullPointerException("obj is null in Card.compreTo()");
    } else {
      checkRep();
      throw new ClassCastException("obj is not a Card in Card.compareTo()");
    }
  }
  Card c = (Card)obj;
  int valComp = getValue().compareTo(c.getValue());
  if (valComp != 0) {
    checkRep();
    return valComp;
  } else {
    int suitComp = getSuit().compareTo(c.getSuit());
    checkRep();
    return suitComp;
  }
}
Use try and finally to use checkRep in two places:
public int compareTo(Object obj) {
  checkRep();
  try {
    Card c = (Card)obj; // may throw ClassCastException
    int valComp = getValue().compareTo(c.getValue()); // may throw NullPointerException
    if (valComp != 0) return valComp;
    return getSuit().compareTo(c.getSuit());
  } finally {
    checkRep();
  }
}
This makes the code more readable as well as more maintainable.


©2004 Michael Bolin