First of all, I know how to build a Java application. But I have always been puzzled about where to put my classes. There are proponents for organizing the packages in a str
I think keep it simple and don't over think it. Don't over abstract and layer too much. Just keep it neat, and as it grows, refactoring it is trivial. One of the best features of IDEs is refactoring, so why not make use of it and save you brain power for solving problems that are related to your app, rather then meta issues like code organisation.
I've really come to like Maven's Standard Directory Layout.
One of the key ideas for me is to have two source roots - one for production code and one for test code like so:
MyProject/src/main/java/com/acme/Widget.java
MyProject/src/test/java/com/acme/WidgetTest.java
(here, both src/main/java and src/test/java are source roots).
Advantages:
One rule of thumb about class placement and packages:
Generally speaking, well structured projects will be free of circular dependencies. Learn when they are bad (and when they are not), and consider a tool like JDepend or SonarJ that will help you eliminate them.
I'm a huge fan of organized sources, so I always create the following directory structure:
/src - for your packages & classes
/test - for unit tests
/docs - for documentation, generated and manually edited
/lib - 3rd party libraries
/etc - unrelated stuff
/bin (or /classes) - compiled classes, output of your compile
/dist - for distribution packages, hopefully auto generated by a build system
In /src I'm using the default Java patterns: Package names starting with your domain (org.yourdomain.yourprojectname) and class names reflecting the OOP aspect you're creating with the class (see the other commenters). Common package names like util, model, view, events are useful, too.
I tend to put constants for a specific topic in an own class, like SessionConstants or ServiceConstants in the same package of the domain classes.
Use packages to group related functionality together.
Usually the top of your package tree is your domain name reversed (com.domain.subdomain
) to guarantee uniqueness, and then usually there will be a package for your application. Then subdivide that by related area, so your FileStorageStrategy
might go in, say, com.domain.subdomain.myapp.storage
, and then there might be specific implementations/subclasses/whatever in com.domain.subdomain.myapp.storage.file
and com.domain.subdomain.myapp.storage.database
. These names can get pretty long, but import
keeps them all at the top of files and IDEs can help to manage that as well.
Exceptions usually go in the same package as the classes that throw them, so if you had, say, FileStorageException
it would go in the same package as FileStorageStrategy
. Likewise an interface defining constants would be in the same package.
There's not really any standard as such, just use common sense, and if it all gets too messy, refactor!