DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernizing APIs: Share your thoughts on GraphQL, AI, microservices, automation, and more for our April report (+ enter a raffle for $250!).

DZone Research Report: A look at our developer audience, their tech stacks, and topics and tools they're exploring.

Getting Started With Large Language Models: A guide for both novices and seasoned practitioners to unlock the power of language models.

Managing API integrations: Assess your use case and needs — plus learn patterns for the design, build, and maintenance of your integrations.

Related

  • Coupling and Cohesion: Confounding Yet Critical Concepts
  • Five Java Developer Must-Haves for Ultra-Fast Startup Solutions
  • The Future of Rollouts: From Big Bang to Smart and Secure Approach to Web Application Deployments
  • Mastering Concurrency: An In-Depth Guide to Java's ExecutorService

Trending

  • Amazon Bedrock: Game-Changing Disruption in 4 Sectors
  • Dockerize a Flask Python App: Step-by-Step
  • Evolution of Privacy-Preserving AI: From Protocols to Practical Implementations
  • Code Wisdom 2024: A Yearlong Adventure of Developer Enlightenment

Package by Feature Is Demanded

Packaging by feature has its benefits, including lower coupling and higher cohesion. It's great for larger applications, but it also has drawbacks to keep in mind.

Grzegorz Ziemoński user avatar by
Grzegorz Ziemoński
·
Mar. 03, 17 · Tutorial
Like (33)
Save
Tweet
Share
29.9K Views

Join the DZone community and get the full member experience.

Join For Free

In the DZone comments under my post about Layered Architecture, some people believed that layering should be realized as what I call Packaging by Feature. I intentionally delayed writing about this to cover hexagons and onions first but now that we have those behind us, we can jump straight into the so demanded architectural style.

What Is Package by Feature?

In a typical Layered Architecture, code organization follows the horizontal decomposition created by dividing the system into layers. This is what is often called Package by Layer.

The problem with this approach is that cohesion inside each package is usually low and the coupling between packages is very high. This seems like exactly the opposite of what we want to achieve. At the same time, most people agree that separating the concerns of presentation, application, domain, and infrastructure makes sense. Package by Feature capitalizes on both points by moving the layering a level down — to the class level — and focusing on coupling and cohesion at a higher level by keeping all classes related to the same feature in the same package/module:

You might wonder now what is a feature? It’s a valid question. I have seen different implementations and examples, varying from a feature meaning effectively one use case to feature meaning a whole set of operations related to a particular business concern. I have seen more of the latter when doing research for this article, but I don’t think it’s necessarily a good thing.

The Essence of Package by Feature

I see two things that form the essence of Package by Feature: maintaining high cohesion and low coupling at the package/module level and being able to say what an application does by looking at its package/module structure.

In a typical Layered Architecture, the cohesion inside a package is low and the coupling between the packages is high. We rarely change technologies or conventions regarding a particular layer, comparing to how often we add a single feature, hence low cohesion. And, in most cases, each class in a layer (package) depends on at least one class in another layer (package), making the coupling between them high. In Package by Feature style, we ideally change classes only in a single package – the one related to the feature we’re working on – so cohesion is high, and there are only a few dependencies between features, so coupling is low.

The two terms above are useful but, to be honest, these are nerd metrics. The more human side of Package by Feature is that you don’t have to be a nerd that knows every piece of a codebase to be able to say what it does – a quick look at the package/module structure should tell you that. This is one step towards what Uncle Bob calls Screaming Architecture.

package com.ecommerce.catalog; // enables user to browse the products
package com.ecommerce.checkout; // enables user to make an order
package com.ecommerce.orders; // enables the shop to process the orders


Implementing Package by Feature

The name Package by Feature strongly suggests that you should implement this style by putting each feature in a separate package and that’s mostly true. The only caveat that I see is that it could also be a module, namespace or any other mechanism available in your language in case you’re not using Java.

The second important thing about Package by Feature is that when related stuff is in a single package, one can finally make some use of access modifiers i.e. make most of the things package-local instead of public. This way we can limit the public interface of our feature to just the things that we actually want to expose. In the Package by Layer style, this was not possible because related classes needed to communicate across packages, which forces us to make everything public.

Example

Even though I feel like Spring Pet Clinic is not the best resource to learn about software development from, it does a pretty good job at presenting a flavor of Package by Feature. The features, in this case, are sets of operations performed on same domain objects:

As you can see, we have three dominating features here – managing owners, vets and visits. Whether this decomposition into features is good or not, is a very complicated topic. At the moment, we should focus on the fact that classes representing different layers like controllers, repositories, and domain objects are all kept together, and that the package structure is more feature-oriented.

Benefits of Package by Feature

  • More Informative Package Structure – you can deduce some of the system’s main features or behaviors from the code structure
  • High Cohesion & Low Coupling – we explained this point already in the essence part, although a bit idealistically
  • Better Encapsulation – you can make effective use of access modifiers to hide the information that’s ought to stay hidden
  • Better Growth Potential, in the code volume sense – unless you develop too big or too small features, you shouldn’t encounter the problem of too big or too many packages

Drawbacks of Package by Feature

  • Unspecified Feature Size – I found no clear guidance or proof that one understanding of feature is better than the other
  • Learning Curve – the concept is simple, but since you need to find your own way to slice a system into features, mastering it can be really hard
  • Messiness Potential – in a tangled domain, in which everything is connected to everything, the slicing into features might become artificial and the low coupling promise might not be fulfilled

When to Use Package by Feature?

Obviously, it can work for smaller applications in which you can shuffle stuff around and try different things at a very low cost. At the same time, since it carries the promise of higher cohesion, lower coupling, and better growth potential, it seems like a perfect fit for bigger applications, which could actually suffer from the drawbacks of packaging by layer. Given its moderate learning curve i.e. the necessity to sort out the best definition of a feature, I’d be wary of using it for the first time when working on a critical application. I’d opt for dividing the problem into bounded contexts and implementing each one in a layered/hexagonal way instead.

Summary

Packaging by Feature is a really appealing idea and I’m totally not surprised that a lot of people push it forward. Our favorite nerdy metrics like cohesion and coupling seem good, and we can see what the application is doing by simply looking at packages. At the same time, I can see its drawbacks and the potential to become a huge mess if someone tries to use an artificial slicing into features in a tangled domain. If you know how to leverage its benefits effectively, go for it. If you don’t, be careful.

application Cohesion (computer science)

Published at DZone with permission of Grzegorz Ziemoński, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Coupling and Cohesion: Confounding Yet Critical Concepts
  • Five Java Developer Must-Haves for Ultra-Fast Startup Solutions
  • The Future of Rollouts: From Big Bang to Smart and Secure Approach to Web Application Deployments
  • Mastering Concurrency: An In-Depth Guide to Java's ExecutorService

Comments

Partner Resources

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: