Spring Boot Code Structure: Package by Layer vs Package by Feature

Akın Topbaş
3 min readMay 10, 2024

--

When structuring a Spring Boot application, developers often face the decision between two common approaches: “Package by Layer” and “Package by Feature.” Both have distinct advantages and disadvantages, influencing their suitability for different project contexts. Let’s explore them with clearer examples.

Package by Feature vs Package by Layer

Package by Layer

Package by Layer is an approach where software components are organized based on functional layers within the application. Each layer represents a distinct responsibility in the application architecture.

com.example.myapp
├── controller
│ ├── UserController.java
│ ├── ProductController.java
│ └── ...
├── service
│ ├── UserService.java
│ ├── ProductService.java
│ └── ...
├── repository
│ ├── UserRepository.java
│ ├── ProductRepository.java
│ └── ...
├── model
│ ├── User.java
│ ├── Product.java
│ └── ...
├── configuration
│ ├── AppConfig.java
│ ├── SecurityConfig.java
│ └── ...
└── util
├── StringUtils.java
└── ...

Pros:

  • Clear Separation of Concerns: Each layer has a specific responsibility, making the codebase easier to understand and maintain.
  • Modifiability: Changes in one layer are less likely to impact other layers, leading to a more flexible architecture.

Cons:

  • Rigid Structure: Adding new features may require modifications across multiple layers, potentially leading to increased development time.
  • Modularity: Since each layer is limited to classes related to a particular layer, it is difficult to break code down into a microservice later on.
  • Testability: Since classes are public, they can be accessed by tests in any package. This allows you to write less focused tests.

OOP Evaluation:

  • Single Responsibility Principle (SRP): Package by Layer aligns with SRP by assigning specific responsibilities to each layer, promoting code maintainability and clarity.
  • Encapsulation: Most classes must be public.

Package by Feature

Package by Feature is an approach where software components are organized based on features or functionalities. Each feature is self-contained within its own package, containing all necessary components.

com.example.myapp
├── user
│ ├── UserController.java
│ ├── UserService.java
│ ├── UserRepository.java
│ └── User.java
├── product
│ ├── ProductController.java
│ ├── ProductService.java
│ ├── ProductRepository.java
│ └── Product.java
├── config
│ ├── AppConfig.java
│ ├── SecurityConfig.java
│ └── ...
└── util
├── StringUtils.java
└── ...

Pros:

  • High Cohesion: Components related to a feature are grouped together, promoting better encapsulation and maintainability.
  • Independent Deployment: Features can be developed and deployed independently, reducing the risk of unintended side effects.
  • Modularity: Since each package is limited to classes related to a particular feature, it is easy to break code down into a microservice later on.
  • Maintainability: Reduces the need to navigate between packages since all classes needed for a feature are in the same package.
  • Testability: Since classes are not public, they can only be accessed by tests in the same package. This allows you to write more focused tests.

Cons:

  • Crosscutting Concerns: Shared functionalities such as logging or security may lead to duplicated code across multiple features.
  • Navigation Complexity: Navigating through the project structure can be challenging, especially when a class is shared among multiple features.

OOP Evaluation:

  • High Cohesion: Package by Feature supports high cohesion by grouping related classes within the same package, promoting better encapsulation and reducing dependencies.
  • Encapsulation: Each feature encapsulates its classes and functionalities, limiting the scope of changes and promoting modular design.

Cohesion represents the relationship within a module. Coupling represents the relationships between modules.

👍 Good (loose coupling, high cohesion)

👎 Bad (high coupling, low cohesion)

Encapsulation: In software systems, encapsulation refers to the bundling of data with the mechanisms or methods that operate on the data. It may also refer to the limiting of direct access to some of that data, such as an object’s components.

Conclusion

Both Package by Layer and Package by Feature have their own advantages and disadvantages. The choice between them depends on factors such as project requirements, team preferences, and the desired level of modularity. It’s essential to evaluate these factors carefully to determine the most suitable approach for a given project.

Both approaches are compatible with OOP principles, but they emphasize different aspects. Package by Layer supports SRP, while Package by Feature provides higher cohesion and less dependency. Considering project requirements and team preferences, it’s important to evaluate which approach is most suitable.

References

Happy Coding! 👨‍💻👩‍💻

--

--