Pros and cons of organizing the packages in the Java project
As projects that I'm working on grow larger and larger, I'm starting to be pretty unsure about dividing classes into packages. Suppose the project has a lot of layers and in these layers are interfaces and implementation and even more sublayers (components). I always end up with a lot of packages which starts to be little confusing.
So I want to know other people's approaches to working with packages. Do you prefer to have a lot of packages with few classes or few packages with a lot of classes? Do you prefer to s开发者_开发技巧eparate implementations from interfaces? And so on... In general your daily habits of using packages and pros/cons of your approach.
Thank you for your posts.
Packages are meant to help you find things.
If they make it more confusing than it is, you're not doing something quite right. If the package structure isn't intuitive, it can actually be harder to find classes than in a flat structure.
There are two basic schools of organising classes into packages as far as I know:
- Organising by module first. Here your higher level packages are different modules of the system and you might split it further by function.
- Organising by function. Here you organise by function first (e.g. all controller classes in one package, all your data containers in another and so on) and optionally subdivide it by module.
There are pros and cons for both systems, I find them roughlty equal, although I prefer the module approach slightly.
The really important thing is though to follow one system and don't mix it with the other. Don't shoehorn classes into packages they don't belong to and don't be afraid to create a new package if your new class doesn't seem to belong to any of your existing ones.
If a package seems to have grown too large, you might want to split it. But the decision of whether a package should be split or not should be made on whether there is a clear conceptual divide between classes therein and not on numbers. A package with a single class is just as good as a package with thirty classes if it's obvious why they're there.
As for separating interfaces and implementations, first off, I'd probably question the need for them. Ever so often I come across interfaces with only one reasonable implementation, which makes me question their reason to exist. (Sometimes there is a good reason, but often there isn't.)
But if you have multiple implementations for a given interface, then yes, I'd separate them. The interface would be com.foo.Bar
and the implementations would be something like com.foo.bars.CrowBar
, com.foo.bars.TaskBar
for example. Obviously, if your implementations belong to different modules, then you would change it to com.foo.moduleX.bars.CrowBar
or com.foo.bars.moduleX.CrowBar
, depending on which system you're following.
Re-reading all this, it does sound kind of complicated, but probably the first sentence is the most important: don't follow packaging principles blindly, packages should help you find classes, not hinder you.
I prefer to limit the scope of my classes and methods to private or package protected wherever possible (so they don't clutter Eclipse's autocomplete:) which automatically means that packages can contain quite a few classes.
I do prefer to separate business data objects (DAO's) from their repositories/retrieval services, which are separated from business logic objects and views.
Sets of related functionality with no cross dependencies tend to go in their own artifact as I tend to reuse logic. Especially handy when you start playing with OSGi and independent services.
One thing is important, the publicly exported interface (public interfaces, enums and classes) need to be somewhat related so the package documentation shows some cohesion.
精彩评论