Naming conventions and best practices for packagesThe name of the package should be in small letters. It is suggested to start the name of the package with the top level domain level followed by sub domains, ex: com. example. tutorialspoint.
There are problems on many different levels: you can't import classes in the default package from classes that are not. you will get class loading problems if you try to resolve the default package in multiple artifacts. you can no longer use the default and protected scope like you normally can.
Java classes are further organized in Java packages, which are visible in the source code. Java packages correspond directly to the directory structure of a Java project. The convention for package naming is that package names correspond to the domain name of the organization that provides the package.
I organize packages by feature, not by patterns or implementation roles. I think packages like:
beans
factories
collections
are wrong.
I prefer, for example:
orders
store
reports
so I can hide implementation details through package visibility. Factory of orders should be in the orders
package so details about how to create an order are hidden.
Package organization or package structuring is usually a heated discussion. Below are some simple guidelines for package naming and structuring:
com.company.product.modulea
com.company.product.module.web
or com.company.product.module.util
etc.com.company.product.model
and com.company.product.util
, etc.After a few experiments and trials you should be able to come up with a structuring that you are comfortable with. Don't be fixated on one convention, be open to changes.
Short answer: One package per module/feature, possibly with sub-packages. Put closely related things together in the same package. Avoid circular dependencies between packages.
Long answer: I agree with most of this article
I prefer feature before layers, but I guess it depends on you project. Consider your forces:
Example:
com/company/module
+ feature1/
- MainClass // The entry point for exploring
+ api/ // Public interface, used by other features
+ domain/
- AggregateRoot
+ api/ // Internal API, complements the public, used by web
+ impl/
+ persistence/
+ web/ // presentation layer
+ services/ // Rest or other remote API
+ support/
+ feature2/
+ support/ // Any support or utils used by more than on feature
+ io
+ config
+ persistence
+ web
This is just an example. It is quite formal. For example it defines 2 interfaces for feature1. Normally that is not required, but could be a good idea if used differently by different people. You may let the internal API extend the public.
I do not like the 'impl' or 'support' names, but they help separate the less important stuff from the important (domain and API). When it comes to naming I like to be as concrete as possible. If you have a package called 'utils' with 20 classes, move StringUtils
to support/string, HttpUtil
to support/http and so on.
Are there best practices with regards to the organisation of packages in Java and what goes in them?
Not really no. There are lots of ideas, and lots opinions, but real "best practice" is to use your common sense!
(Please read No best Practices for a perspective on "best practices" and the people who promote them.)
However, there is one principal that probably has broad acceptance. Your package structure should reflect your application's (informal) module structure, and you should aim to minimize (or ideally entirely avoid) any cyclic dependencies between modules.
(Cyclic dependencies between classes in a package / module are just fine, but inter-package cycles tend to make it hard understand your application's architecture, and can be a barrier to code reuse. In particular, if you use Maven you will find that cyclic inter-package / inter-module dependencies mean that the whole interconnected mess has to be one Maven artifact.)
I should also add that there is one widely accepted best practice for package names. And that is that your package names should start with your organization's domain name in reverse order. If you follow this rule, you reduce the likelihood of problems caused by your (full) class names clashing with other peoples'.
I've seen some people promote 'package by feature' over 'package by layer' but I've used quite a few approaches over many years and found 'package by layer' much better than 'package by feature'.
Further to that I have found that a hybrid: 'package by module, layer then feature' strategy works extremely well in practice as it has many advantages of 'package by feature':
I explain in depth here: Java Package Name Structure and Organization but my standard package structure is:
revdomain.moduleType.moduleName.layer.[layerImpl].feature.subfeatureN.subfeatureN+1...
Where:
revdomain Reverse domain e.g. com.mycompany
moduleType [app*|framework|util]
moduleName e.g. myAppName if module type is an app or 'finance' if its an accounting framework
layer [model|ui|persistence|security etc.,]
layerImpl eg., wicket, jsp, jpa, jdo, hibernate (Note: not used if layer is model)
feature eg., finance
subfeatureN eg., accounting
subfeatureN+1 eg., depreciation
*Sometimes 'app' left out if moduleType is an application but putting it in there makes the package structure consistent across all module types.
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