The Java Course provides a general introduction to programming in Java. It is based on A.B. Downey's book, How to Think Like a Computer Scientist. Click here for details.


Incremental Development vs. Planning

In this chapter I have demonstrated an approach to program development I refer to as rapid prototyping with iterative improvement. In each case, I wrote a rough draft (or prototype) that performed the basic calculation, and then tested it on a few cases, correcting flaws as I found them.

Although this approach can be effective, it can lead to code that is unnecessarily complicated---since it deals with many special cases---and unreliable---since it is hard to convince yourself that you have found all the errors.

An alternative is high-level planning, in which a little insight into the problem can make the programming much easier. In this case the insight is that a Time is really a three-digit number in base 60! The second is the "ones column," the minute is the "60's column", and the hour is the "3600's column."

When we wrote addTime and increment, we were effectively doing addition in base 60, which is why we had to "carry" from one column to the next.

Thus an alternate approach to the whole problem is to convert Times into doubles and take advantage of the fact that the computer already knows how to do arithmetic with doubles. Here is a method that converts a Time into a double:

  public static double convertToSeconds (Time t) {
    int minutes = t.hour * 60 + t.minute;
    double seconds = minutes * 60 + t.second;
    return seconds;
  }

Now all we need is a way to convert from a double to a Time object. We could write a method to do it, but it might make more sense to write it as a third constructor:

  public Time (double secs) {
    this.hour = (int) (secs / 3600.0);
    secs -= this.hour * 3600.0;
    this.minute = (int) (secs / 60.0);
    secs -= this.minute * 60;
    this.second = secs;
  }

This constructor is a little different from the others, since it involves some calculation along with assignments to the instance variables.

You might have to think a bit to convince yourself that the technique I am using to convert from one base to another is correct. Assuming you are convinced, we can use these methods to rewrite addTime:

  public static Time addTime (Time t1, Time t2) {
    double seconds = convertToSeconds (t1) + convertToSeconds (t2);
    return new Time (seconds);
  }

This is much shorter than the original version, and it is much easier to demonstrate that it is correct (assuming, as usual, that the methods it invokes are correct). As an exercise, rewrite increment the same way.



Last Update: 2011-01-24