18. Cleanup and Multiple Source Files
Part of
CS:2820 Object Oriented Software Development Notes, Fall 2015
|
In our road network simulator, there are many bug messages. Some have to do with extending the simulator to more interesting models, adding stop signs, making source intersections pump out multiple vehicles instead of just one, making vehicles have an identity and current location, and so on.
But the code also contains junk left over from poorly thought out development process. It is time to clean this up! There is a global class Event which we never used! Instead, class Simulator contains an inner class for this.
Class ByName is only explicitly used inside SyntaxCheck. While it is implictly used elsewhere in lambda bindings, this class need not be global, it can be a public inner class of SyntaxCheck.
The code is getting large, approaching 680 lines. At some point, it would make good sense to break it into multiple source files. The Java compiler allows you to say:
[HawkId ~]$ javac File1.java File2.java
This builds a project where the source is written in multiple files. However, if you had to type all the file names every time you compiled your program, it would get very tiring. Fortunately, the Unix/Linux shells (as well as the DOS/Windows command line) provide an abbreviation in the form of a wild-card character that matches essentially anything, so you can type:
[HawkId ~]$ javac *.java
Simulator.java RoadNetwork.java
Given that this file exists, you can compile these two source files together with the command
[HawkId ~]$ javac @classes
If the classes file gets big, it would be nice to be able to add comments to it. Unfortunately, Java does not have a standard way to put comments in @argfiles.
In the above example, we assumed that the classes file specified a separate source file for class Simulator. We can break this out of the original monolithic source file like this:
// Simulator.java /** * Framework for discrete event simulation. * @author Douglas Jones * @version ... */ import java.util.PriorityQueue; class Simulator { public interface Action { // actions contain the specific code of each event void trigger( float time ); } ... remainder of body of class ... }
Note that our original source file had imported a large number of different classes. Of those, only class PriorityQueue is relevant to class Simulator, so that is the only import statement used in this source file.
Note also that the header comments from class Simulator have been moved up into the header comment for the file, and note that the header comments for the file include indications of authorship, version and other documentation of the provenance of this file.
Class Simulator is almost the perfect size for a single class that fits comfortably in one source file. Some of our other classes are rather small, and we will investigate splitting them out into separate packages.
In our example classes file, the remainder of the file aside from class Simulator was still in the file RoadNetwork.java. With the removal of class Simulator, the file RoadNetwork.java could now begin like this:
// RoadNetwork.java /** * Classes that define the topology of a road network and simulate that network. * @author Douglas Jones * @version MP4? */ import java.util.LinkedList; import java.util.List; import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; import java.util.Random; // import Simulator; ... the remaining classes in our project
Note that the list of import statements has been shortened because of the omission of imports that were only needed in Simulator.java. Of more importance, note that Java does not permit an explicit import of class Simulator. It would have been nice if each file could explicitly reference the other files on which it depended, but Java neither requires nor permits such documentation other than in comments. So, we have included the import statement we wanted to use in a comment.