🔸 TL;DR
Layered packages are fine — sometimes they’re exactly what you need.
But when complexity grows, package-by-feature keeps changes local and reduces accidental coupling. Add package-private internals to enforce boundaries. If you want automated checks + docs + module testing, Spring Modulith builds on the same idea with tooling.

🔸 THREE-TIER ARCHITECTURE (THE CLASSIC)
The traditional split is:
▪️ View → controllers / web layer (HTTP, UI)
▪️ Business → services / domain logic
▪️ Data → repositories / persistence
This separation still makes sense — but the way we mirror it in packages can become limiting as the app grows.
🔸 THE CLASSIC “PACKAGE BY LAYERS” CODEBASE
Typical structure:
▪️ controller/ → all controllers
▪️ service/ → all services
▪️ repository/ (or data/) → all repos
▪️ model/ → all entities/DTOs
✅ Works well when:
▪️ the codebase is small/medium
▪️ the domain is simple
▪️ the team is stable and conventions are strong
⚠️ Gets harder when features multiply:
😵 understanding “Orders” requires jumping across many packages
😵 changes spread across the whole project
😵 “service calls service calls service” becomes common
🔸 PACKAGE BY FEATURES (VERTICAL SLICES)
Instead of grouping by type, group by feature:
▪️ features/orders/
▪️ controller + service + repo + model
▪️ features/payments/
▪️ controller + service + repo + model
✅ Benefit: when you work on a feature, you stay in one place.
✅ Code that changes together… lives together. 📦
🔸 ENFORCE BOUNDARIES WITH PACKAGE-PRIVATE
package-private:
▪️ Make internals package-private: impls, helpers, repos, most models
▪️ Expose only a small public API per feature (facade / interface)
▪️ Avoid cross-feature “quick calls” that slowly create coupling chaos
🧠 Goal: features collaborate intentionally — not accidentally.
🔸 WHAT ABOUT SPRING MODULITH?
▪️ Package-by-feature =a structuring strategy + conventions you enforce
▪️ Spring Modulith =the same mindset plus tooling to model and validate modules
Spring Modulith can help you:
▪️ define/detect modules
▪️ verify boundaries (no illegal dependencies, no cycles)
▪️ generate documentation/diagrams
▪️ test modules with dedicated support
…as part of a “modular monolith” approach in the Spring ecosystem
🔸 TAKEAWAYS
▪️ Packaging by layers isn’t “wrong” — it just has scaling limits
▪️ Package-by-feature improves navigation and keeps changes localized
▪️ Package-private helps prevent cross-feature spaghetti
▪️ Spring Modulith adds verification, documentation, and module testing to this modular approach
#java #spring #springboot #architecture
Go further with Java certification:
Java👇
Spring👇
SpringBook👇
JavaBook👇