Tuesday, December 9, 2014

Importing and Packages - Customs won't like this.

Alright, I've been ignoring it, but the time has come to take on a fairly important issue when it comes to organizing your code.  The topic of the day is packaging.

Packages are really not much more than a set of directories (or folders if you prefer) into which your .class files are placed.  This becomes important once your projects get beyond two or three .java files, because you really want to avoid namespace clashes.  You don't even know what they are yet but I'll bet you're agreeing that they sound like something to avoid.  More importantly, proper packaging will help you to keep your workspace and brain organized.  Programming is hard enough, you don't need to make it worse on yourself.  I may keep a messy desk but I do try to have my source code laid out in a logical fashion.

Most of the time, we bundle up our .class files into something called a Jar.  This is just a file with a .jar extension, and it's actually in technical terms a .zip archive file.  This is convenient because a sizeable system can contain dozens or hundreds of .class files, and managing them individually will make you want to gnaw your foot off.

Now, we could go ahead and just put all of the .class files into one giant list.  But that's not a list you want to be looking at or searching through.  It is almost always possible to separate out the various parts of a project into logical subsections, and you should do this.

At the most basic level, you can control packaging by putting a line at the top of your source file like this one:

    package com.oopuniversity.packages;

It dictates that the compiled .class file should be placed in a subdirectory called 'com.oopuniversity.packages'.  When you want to refer to a class called 'PackageDemo' in your java code, you can do it either the hard way:

    com.oopuniversity.packages.PackageDemo = new com.oopuniversity.packages.PackageDemo();

Or you can do it the easy way.  Add an 'import' line up above your class declaration like this:

   import com.oopuniversity.packages.PackageDemo;

This applies to any class that is not in the same package as the class on which you're working.  For classes within the same package the import statement is unnecessary.'

IDEs make this whole process really easy.  You tell them to create a new package, and they do so, creating all of the necessary directories for both java and class files.  You try to create an object and they can automatically figure out that you need an import statement and add it for you.  When they build the code, it's placed in the correct location.

At first this may seem like a needless complication, but it pays off as soon as you're doing any work that is not extremely basic in nature.

The rules for package names are simple.  While it's not hard and fast, stick to lower case letters.  Separate individual words with periods.  You can call them anything you like, but it's generally a good idea to go from less specific to more specific.  Most of the standard packages that come in the Java libraries start with 'java.' and most third party packages start off with the domain name of the developer (this 'com.oopuniversity') and are then followed by as many identifiers as needed for your purposes.  It is a good idea to organize this way, because if you use the same package names as someone else does you could badly confuse your ClassLoader and this leads to really irritating situations when you try to get programs to actually run.  In short, 'util' is a pretty bad package name, but 'org.mycompany.util' is better.  'org.mycompany.secretproject.util' is even better yet.

In summary:

Organize your code into packages.
Specify the package name at the top of your source file.
Import the classes you need by specifying their packages in import statements.

There are specific packaging rules I like to follow when building systems, related to how the code itself is structured.  I'll talk about those rules when it's appropriate.  Those are going to be more on the order of recommendations, but it won't hurt you (much) to go along with them.