The next thing to sort out is how to build the project, i.e. how to run the compiler and the unit tests. This is very frequent in agile development (only a few lines are written before re-compiling and re-testing). So it needs to be convenient. Also, during refactoring, it should be easy to compile and test classes one by one, even when classes that haven't been tackled yet are still broken. Some developers would want to use an IDE or sophisticated build tool for compilation. But what is the simplest thing that works properly?
A reasonably simple Makefile will do. In the Java case, Java source files can
be put in a folder java
and the compiled class files can be put in
a folder bin
. Then a Makefile in the java
folder can
be written like this:
Entity Grid Display Help: javac -d ../bin $@.java java -cp ../bin $@ clean: rm -f ../bin/*.class
The first rule allows you to type in any single class name, e.g. make
Entity
. The class is compiled, along with any recently edited classes
that it depends on, and the unit tests for the class are run. There is no need
to mention dependencies in the makefile, because the Java compiler checks file
timestamps and recompiles other classes as necessary. The entire program can be
compiled and run by using make
on its topmost driver class.
The compiler gets confused occasionally, when obsolete class files are left
lying around, so the make clean
option is provided, to be used when
a class is deleted or renamed.
The simple Makefile shown above assumes that all the classes are in the
default package. As the number of classes in a project grows, it gets
increasingly clumsy for them all to be lumped together rather than classified
into separate package folders. But the makefile approach can be extended fairly
simply. Suppose there are two packages, model
and
view
. Then the makefile could look like this:
Entity Grid: javac -d ../bin model/$@.java java -cp ../bin model.$@ Display Help: javac -d ../bin view/$@.java java -cp ../bin view.$@ clean: rm -f ../bin/model/*.class rm -f ../bin/view/*.class
A class can still be compiled using its short class name, e.g. make
Entity
. The lists of classes in each package need to be maintained when
a class is added, removed or renamed, but the effort involved is not great.