227

A little while ago, I saw a question answered here regarding the fine-grained organization of Java packages. For example, my.project.util, my.project.factory, my.project.service, etc.

Are there best practices with regards to the organization of packages in Java and what goes in them?

How do you organize your classes in your Java project?

For instance, a project I'm working on with a few people has a package called beans. It started out being a project containing simple beans, but it has ended up (through poor experience and lack of time) containing everything (almost). I've cleaned them up a little, by putting some factory classes in a factory package (classes with static methods that create beans), but we have other classes that do business logic and others that do simple processing (not with business logic) like retrieving a message for a code from a properties file.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Cyntech
  • 5,362
  • 6
  • 33
  • 47
  • 100
    I disagree with the closing of this question. I don't disagree that best practice questions are almost always based on experience and opinion, however, I disagree that these questions should be closed on Stack Overflow. This is the crux of good programming, using best practices and finding the best solution uses these opinions and experiences. Please re-open this question. – Cyntech Aug 03 '15 at 05:17
  • 2
    I suggest that you read this: https://www.satisfice.com/blog/archives/5164. TL;DR ... the whole idea of "best practices" is broken. At best it is an egregious misnomer, at worst it is downright harmful. – Stephen C Jun 16 '20 at 23:21

7 Answers7

214

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.

informatik01
  • 16,038
  • 10
  • 74
  • 104
onof
  • 17,167
  • 7
  • 49
  • 85
  • 10
    This post makes a good point about package visibility. I've never seen Java package scope in use, but the right package structure could allow developers to take better advantage of it. – Jpnh Mar 23 '13 at 02:14
  • 25
    This is exactly right, but few developers do this. Packages should be cohesive collections of classes, some of which are visible only within the package. That would minimize coupling between classes that should not be coupled because they pertain to different features. The package-by-layer approach, does not take advantage of package visibility modifiers, and packages in such a project have low cohesion and a high degree of coupling between packages. – Nate Reed Aug 17 '13 at 20:15
  • Do you have example of this? I am using Spring-MVC i find it hard to organize it by feature/module because spring uses config xml. – Eric Huang Jun 21 '16 at 23:29
  • 2
    @onof I also organize my code by feature but what's the best practices for base classes shared by all features? – Marc Jun 30 '16 at 15:12
  • I was following the first style. but now i have to jump from one package to another when working with classes. it really makes a bad experience. I am now switching to second style because i think it will be easier to follow related classes together. – M.kazem Akhgary Dec 14 '18 at 11:45
  • @Marc they IMO should be in the root of the packages – onof Dec 10 '19 at 11:46
  • @onof I know this is an old answer/question, but what about organizing interfaces in a packages structured as you suggested? – Renato Oct 13 '21 at 14:08
198

Package organization or package structuring is usually a heated discussion. Below are some simple guidelines for package naming and structuring:

  • Follow Java package naming conventions
  • Structure your packages according to their functional role as well as their business role
    • Break down your packages according to their functionality or modules. e.g. com.company.product.modulea
    • Further break down could be based on layers in your software. But don't go overboard if you have only few classes in the package, then it makes sense to have everything in the package. e.g. com.company.product.module.web or com.company.product.module.util etc.
    • Avoid going overboard with structuring, IMO avoid separate packaging for exceptions, factories, etc. unless there's a pressing need.
  • If your project is small, keep it simple with few packages. e.g. com.company.product.model and com.company.product.util, etc.
  • Take a look at some of the popular open source projects out there on Apache projects. See how they use structuring, for various sized projects.
  • Also consider build and distribution when naming (allowing you to distribute your API or SDK in a different package, see the servlet API)

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
naikus
  • 24,302
  • 4
  • 42
  • 43
  • Thanks for your response. This is largely what we have tried to encompass, but a lot of unrelated code got into our beans package, which is where my question came from. – Cyntech Jul 14 '10 at 00:36
  • 4
    I agree package by feature makes the most sense. I heard a great analogy once related to a company office structure. In a layered approach, each of the individuals per level in a company would sit with each other i.e. Executives, managers, admin, employees/workers all sit in separate sections in a building. This structure is likely not as effective as a "feature" organized approach. I.e. if the Sales Executive sits with the Sales Manager who sits with the Sales employees who all sit with a Sales Admin. This provides better cohesion between the department when organized this way. – alex Feb 25 '19 at 16:58
  • Agree with your points. Just one point to highlight about company name in package some times company gets aquired product gets sold. Management want to remove company name. That could be overhead. – Tushar D Oct 02 '19 at 08:32
47

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

Peter Tseng
  • 13,613
  • 4
  • 67
  • 57
24

I prefer feature before layers, but I guess it depends on your project. Consider your forces:

  • Dependencies
    Try minimize package dependencies, especially between features. Extract APIs if necessary.
  • Team organization
    In some organizations teams work on features and in others on layers. This influence how code is organized, use it to formalize APIs or encourage cooperation.
  • Deployment and versioning
    Putting everything into a module make deployment and versioning simpler, but bug fixing harder. Splitting things enable better control, scalability and availability.
  • Respond to change
    Well organized code is much simpler to change than a big ball of mud.
  • Size (people and lines of code)
    The bigger the more formalized/standardized it needs to be.
  • Importance/quality
    Some code is more important than other. APIs should be more stable then the implementation. Therefore it needs to be clearly separated.
  • Level of abstraction and entry point
    It should be possible for an outsider to know what the code is about, and where to start reading from looking at the package tree.

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 two interfaces for feature1. Normally that is not required, but it 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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ThomasGran
  • 341
  • 2
  • 5
15

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 principle 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'.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
11

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: the 'package by module, layer then feature' strategy works extremely well in practice as it has many advantages of 'package by feature':

  • Promotes creation of reusable frameworks (libraries with both model and UI aspects)
  • Allows plug and play layer implementations - virtually impossible with 'package by feature', because it places layer implementations in the same package/directory as the model code.
  • Many more...

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 it’s an accounting framework

  • layer [model|ui|persistence|security etc.,]

  • layerImpl, e.g., wicket, jsp, jpa, jdo, hibernate (Note: not used if layer is model)

  • feature, e.g., finance

  • subfeatureN, e.g., accounting

  • subfeatureN+1, e.g., depreciation

*Sometimes 'app' is left out if moduleType is an application, but putting it in there makes the package structure consistent across all module types.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Volksman
  • 1,969
  • 23
  • 18
6

I'm not aware of standard practices for package organization. I generally create packages that cover some reasonably broad spectrum, but I can differentiate within a project. For example, a personal project I'm currently working on has a package devoted to my customized UI controls (full of classes subclassing swing classes). I've got a package devoted to my database management stuff, I've got a package for a set of listeners/events that I've created, and so on.

On the other hand I've had a coworker create a new package for almost everything he did. Each different MVC he wanted got its own package, and it seemed a MVC set was the only grouping of classes allowed to be in the same package. I recall at one point he had 5 different packages that each had a single class in them. I think his method is a little bit on the extreme (and the team forced him to reduce his package count when we simply couldn't handle it), but for a nontrivial application, so would putting everything in the same package. It's a balance point you and your teammates have to find for yourself.

One thing you can do is try to step back and think: if you were a new member introduced to the project, or your project was released as open source or an API, how easy/difficult would it be to find what you want? Because for me, that's what I really want out of packages: organization. Similar to how I store files in folder on my computer, I expect to be able to find them again without having to search my entire drive. I expect to be able to find the class I want without having to search the list of all classes in the package.

Ardent Coder
  • 3,777
  • 9
  • 27
  • 53
Brian S
  • 4,878
  • 4
  • 27
  • 46