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.


Program Development

At this point you should be able to look at complete Java methods and tell what they do. But it may not be clear yet how to go about writing them. I am going to suggest one technique that I call incremental development.

As an example, imagine you want to find the distance between two points, given by the coordinates (x1, y1) and (x2, y2). By the usual definition,

distance = sqrt((x2 - x1)2 + (y2 - y1)2)

The first step is to consider what a distance method should look like in Java. In other words, what are the inputs (parameters) and what is the output (return value).

In this case, the two points are the parameters, and it is natural to represent them using four doubles, although we will see later that there is a Point object in Java that we could use. The return value is the distance, which will have type double.

Already we can write an outline of the method:

  public static double distance
               (double x1, double y1, double x2, double y2) {
    return 0.0;
  }

The statement return 0.0; is a place-keeper that is necessary in order to compile the program. Obviously, at this stage the program doesn't do anything useful, but it is worthwhile to try compiling it so we can identify any syntax errors before we make it more complicated.

In order to test the new method, we have to invoke it with sample values. Somewhere in main I would add:

    double dist = distance (1.0, 2.0, 4.0, 6.0);

I chose these values so that the horizontal distance is 3 and the vertical distance is 4; that way, the result will be 5 (the hypotenuse of a 3-4-5 triangle). When you are testing a method, it is useful to know the right answer.

Once we have checked the syntax of the method definition, we can start adding lines of code one at a time. After each incremental change, we recompile and run the program. That way, at any point we know exactly where the error must be---in the last line we added.

The next step in the computation is to find the differences x2 - x1 and y2 - y1. I will store those values in temporary variables named dx and dy.

  public static double distance
               (double x1, double y1, double x2, double y2) {
    double dx = x2 - x1;
    double dy = y2 - y1;
    System.out.println ("dx is " + dx);
    System.out.println ("dy is " + dy);
    return 0.0;
  }

I added print statements that will let me check the intermediate values before proceeding. As I mentioned, I already know that they should be 3.0 and 4.0.

When the method is finished I will remove the print statements. Code like that is called scaffolding, because it is helpful for building the program, but it is not part of the final product. Sometimes it is a good idea to keep the scaffolding around, but comment it out, just in case you need it later.

The next step in the development is to square dx and dy. We could use the Math.pow method, but it is simpler and faster to just multiply each term by itself.

  public static double distance
               (double x1, double y1, double x2, double y2) {
    double dx = x2 - x1;
    double dy = y2 - y1;
    double dsquared = dx*dx + dy*dy;
    System.out.println ("dsquared is " + dsquared);
    return 0.0;
  }

Again, I would compile and run the program at this stage and check the intermediate value (which should be 25.0).

Finally, we can use the Math.sqrt method to compute and return the result.

  public static double distance
               (double x1, double y1, double x2, double y2) {
    double dx = x2 - x1;
    double dy = y2 - y1;
    double dsquared = dx*dx + dy*dy;
    double result = Math.sqrt (dsquared);
    return result;
  }

Then in main, we should print and check the value of the result.

As you gain more experience programming, you might find yourself writing and debugging more than one line at a time. Nevertheless, this incremental development process can save you a lot of debugging time.

The key aspects of the process are:

  • Start with a working program and make small, incremental changes. At any point, if there is an error, you will know exactly where it is.
  • Use temporary variables to hold intermediate values so you can print and check them.
  • Once the program is working, you might want to remove some of the scaffolding or consolidate multiple statements into compound expressions, but only if it does not make the program difficult to read.


Last Update: 2011-01-24