Core Java

Package your classes by Feature and not by Layers

Most of the enterprise Java applications share some similarities in their design. Mostly the packaging of these applications are driven by the framework used by them like Spring, EJBs or Hibernate etc. Alternatively you can group you packages by features. Like any other item regarding modeling this is not free from any issues. Lets discuss some trade-off and how get around them. In this post we will discuss the pros and cons of both approaches against common usage scenarios.

Package By Layer (PBL)

This is a the first thing that developers do when the create an enterprise application in to split it to number of layers like DAO, SERVICE, VIEW etc.. This gives nice
 
separation of code when we use different frameworks at different layers. For example if I were to use Hibernate, Spring and JSF, then I will have all my Hibernate dependent code in the DAO layer and JSF related code in the VIEW Layer. This is sort of good in case I need to migrate to a new framework only at the view layer or DAO Layer.

Package By Feature (PBF)

Package-by-feature uses packages to reflect the feature set. It places all items related to a single feature (and only that feature) into a single directory/package. This results in packages with high cohesion and high modularity, and with minimal coupling between packages. Items that work closely together are placed next to each other. They aren’t spread out all over the application. This also increases coherence as a large percentage of a the dependencies of a class are located close to that class.

Comparing the approaches

Let me compare both the approaches in below dimensions.

1. Adding a new Feature.

In case of PBL code has to be added to VIEW, SERVICE and DAO Layers and it can be tedious. PBF solves this problem by grouping all the code related to same feature in to a single directory.

2. Changing a framework used.

As discussed already PBL makes it easier to change a framework as all the related code are kept at same place. Here we know exactly the scope of the change and its impact. In case of PBF we need to dig into all the feature set to see the framework related classes. If you choose to migrate the framework module by module, then it could be argued that PBF is better than PBL.

3. Code Navigation.

As developers needs to work on the features most of the time using PBF is easier for code navigation. When you know exactly know what has to be done its not much advantage.

4. Keeping the Common Code.

Every application will have some components which will be reused across the features ie, the features are not always exclusive. In such case if we package all the features separately the interactions between them can be quite messy. As a general principle we need to reduce such interactions and increase the cohesion inside the package. We can get around the situation be adding such entities to a common package. This approach is used in many projects including Hibernate.

Conclusion

Most application will have 4 types of classes. ie,

  1. Domain Objects
  2. Business Services
  3. Data Retrieval Logic
  4. Data Representation Logic

If we use PBF it gives us a good structural representation but does not give any functional representation. We need our architecture to resemble the problem domain. So its better to use Package By Feature style. We could internally classify the classes by using naming conventions like MyFeatureDAO or MyFeatureService . This way we could communicate the intend of the classes.

I have found some discussions on this topic and hope that might also help you choose.

  1. Java Practices Article
  2. Lessons to Learn from the Hibernate Core Implementation
  3. How Changing Java Package Names Transformed my System Architecture
  4. Presentation By  Kostis Kapelonis
  5. The Principles of OOD By Uncle Bob
  6. Article says its Better to Use Package By Layer
  7. Question on SO Is package by feature approach good?

 

Manu PK

Manu develops software applications using Java and related technologies. Geek, Tech Blogger, open source and web enthusiast.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

5 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Hendy Irawan
11 years ago

Why not both? We use both and it helps a lot for managing dependencies.
Bundles are grouped first by feature, then in a feature its again split into several bundles for
Data Objects, Shell, JAX-RS, Wicket UI, (the layers).
So the data bundle does not need to depend on e.g. Wicket.

Manu PK
11 years ago
Reply to  Hendy Irawan

You got it right. The point is it should be first split in to feature, then by layers. Some times there may be very few classes so its may not needed to be further split.

stingh711
stingh711
11 years ago

Good idea! But it makes spring’s AOP more difficult to configure.

Karl
11 years ago

Uncle Bob’s OOD Principals that you linked have a much more subtle distinction. He says that there’s a time and place for both strategies, depending on your priorities. In fact, projects often start off packaged by closure (layers that change together) while they’re changing frequently and then later might get repackaged to move to a more stable configuration based on feature to promote more reuse.

It is probably fair to say that good, clean, well designed, reusable code can benefit more from being packaged by feature, but rarely does that describe version 1.0 code.

Vinicius
Vinicius
9 years ago

I think its would be better solved using microservices approach. Think about, why to create all features in the same project if i can simplify that separating by feature?

Back to top button