After doing some research, I got confirmation that folder-by-feature structure is superior to folder-by-layer structure in the majority of cases. To get some arguments we can read, among others, the following articles or even this answer.
Package by features, not layers
Feature folders vs Tech folders
Package by feature, not layer
Package by Layer for Spring Projects Is Obsolete
However, all the DDD project examples that I found are made with package-by-layer, most of the time following a structure like:
├── application
├── config
├── domain
├── infrastructure
└── interfaces
So my question is: why the DDD community does not follow package-by-feature even if it’s apparently superior in the majority of cases?
Should we use package-by-feature with DDD? If so, how to do it?
I mention that I’m not talking about the particular case of micro-service architecture where obviously package-by-layer is more relevant.
Package-by-feature uses packages to reflect the feature set. It tries to place 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.
A typical structure may include a top-level package for all requirements in the model. Each nested package within this package may contain requirements from different specifications, such as the system specification, element specifications, and component specifications.
A layer package (. lpk file) includes the layer properties and the dataset referenced by the layer. With a layer package, you can share everything about the layer—its symbolization, labeling, field properties, and data.
Domain-Driven Design(DDD) is a collection of principles and patterns that help developers craft elegant object systems. Properly applied it can lead to software abstractions called domain models. These models encapsulate complex business logic, closing the gap between business reality and code.
DDD is about domain, so group everything in domain folders. But at the very high level preserve 4 Hexagonal architecture layers. This could be packages for simplicity or best separate modules with strict mutual dependencies (as in Android Instant Apps).
src/main/java
├── UserInterface
│ ├── OneUseCase.java
│ ├── AnotherUseCase.java
│ └── YetAnotherUseCase.java
├── Application
│ ├── SubDomain1
│ │ └── ... (java files)
│ └── SubDomain2
│ └── ... (java files)
├── Domain
│ ├── SubDomain1
│ │ └── ... (java files)
│ └── SubDomain2
│ └── ... (java files)
└── Infrastructure
├── SubDomain1
│ └── technology1 (java files)
│ └── technology2. (java files)
└── SubDomain2
└── technology1 (java files)
└── technology2. (java files)
Here is a a good article wtih clean explanation.
My understanding and my vision of this subject is as follows:
Package by feature is about vertical slicing (structuring the source code according to domain concepts) instead of by horizontal layering (structuring according to technical concepts).
But saying "instead of" isn't completely true, since there's a moment when you have to distinguish between those technical concepts. It would be better to say package by feature first, and then package by layer inside each feature.
In strategic DDD, each Bounded Context (BC) is a vertical slice (a whole application, full stack... with UI, application, domain model and infraestructure layers).
Then, inside a BC, tactical DDD promotes packaging the domain model code by business concepts first, and then by technical concepts (tactical patterns). So you have modules (groups of aggregates that are tightly cohesive and loosely coupled), and inside each aggregate you have entities, value objects, factories, repository. The other layers (UI, application, infra) can be structured by modules as well.
So as a summary DDD does follow a mixed approach:
Packaging by business concepts with different levels of granularity: BCs, modules, aggregates.
Package by layer inside a BC: UI, application, domain, infraestructure.
PD: this subject (source code structure) is explained in Chapter 9 (Modules) of Vaughn Vernon's book "Implementing DDD".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With