Organizing by Layer
The first approach to organizing our code is by layer. We might organize a code like this:
Figure 3.1: When organizing code by layer, functional aspects tend to be mixed
For each of our layers, web, domain, and persistence, we have a dedicated package. As discussed in Chapter 1, What's Wrong with Layers?, simple layers may not be the best structure for our code for several reasons, so we have already applied the Dependency Inversion Principle here, only allowing dependencies toward the domain code in the domain package. We did this by introducing the AccountRepository interface in the domain package and implementing it in the persistence package.
However, we can find at least three reasons why this package structure is suboptimal.
First, we have no package boundary between functional slices or features of our application. If we add a feature for managing users, we will add a UserController to the web package, a UserService, UserRepository, and User to...