A typical structure of a Java program contains the following elements: Documentation Section. Package Declaration. Import Statements.
The Java class hierarchy is a tree. A tree is a kind of structure with a root and the other elements are organized so that each element has one branch connecting it to the root. 1 Every class descends from the class Object (the root of the tree). 2 Every class has exactly one superclass (except the class Object).
A Java application is made up of classes and resources. Resources can be videos, songs, images, text files, data files, etc. There can be thousands of classes and thousands of resource files in one application. Often you will write only some of the classes yourself, and simply use many classes written by others.
Main is the method, which is an essential part of any Java program.
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.
Where I'm working, we're using Maven 2 and we have a pretty nice archetype for our projects. The goal was to obtain a good separation of concerns, thus we defined a project structure using multiple modules (one for each application 'layer'): - common: common code used by the other layers (e.g., i18n) - entities: the domain entities - repositories: this module contains the daos interfaces and implementations - services-intf: interfaces for the services (e.g, UserService, ...) - services-impl: implementations of the services (e.g, UserServiceImpl) - web: everything regarding the web content (e.g., css, jsps, jsf pages, ...) - ws: web services
Each module has its own dependencies (e.g., repositories could have jpa) and some are project wide (thus they belong in the common module). Dependencies between the different project modules clearly separate things (e.g., the web layer depends on the service layer but doesn't know about the repository layer).
Each module has its own base package, for example if the application package is "com.foo.bar", then we have:
com.foo.bar.common
com.foo.bar.entities
com.foo.bar.repositories
com.foo.bar.services
com.foo.bar.services.impl
...
Each module respects the standard maven project structure:
src\
..main\java
...\resources
..test\java
...\resources
Unit tests for a given layer easily find their place under \src\test... Everything that is domain specific has it's place in the entities module. Now something like a FileStorageStrategy should go into the repositories module, since we don't need to know exactly what the implementation is. In the services layer, we only know the repository interface, we do not care what the specific implementation is (separation of concerns).
There are multiple advantages to this approach:
I know this doesn't answer all your questions, but I think this could put you on the right path and could prove useful to others.
Class names should always be descriptive and self-explanatory. If you have multiple domains of responsibility for your classes then they should probably be refactored.
Likewise for you packages. They should be grouped by domain of responsibility. Every domain has it's own exceptions.
Generally don't sweat it until you get to a point where it is becoming overwhelming and bloated. Then sit down and don't code, just refactor the classes out, compiling regularly to make sure everything works. Then continue as you did before.
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!
One thing that I found very helpful for unit tests was to have a myApp/src/ and also myApp/test_src/ directories. This way, I can place unit tests in the same packages as the classes they test, and yet I can easily exclude the test cases when I prepare my production installation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With