107

I make use of an AngularJS style guide. Within this guide there is a style called folder-by-feature, instead of folder-by-type, and I'm actually curious what's the best approach (in this example for Java)

Let's say I have an application where I can retrieve Users & Pets, using services, controllers, repositories and ofcourse domain objects.

Taking the folder-by-..... styles, we have two options for our packaging structure:

1. Folder-by-type

com.example
├── domain
│    ├── User.java
│    └── Pet.java
├── controllers
│    ├── UserController.java
│    └── PetController.java
├── repositories
│    ├── UserRepository.java
│    └── PetRepository.java
├── services
│    ├── UserService.java
│    └── PetService.java
│   // and everything else in the project
└── MyApplication.java

2. Folder-by-feature

com.example
├── pet
│    ├── Pet.java
│    ├── PetController.java
│    ├── PetRepository.java
│    └── PetService.java
├── user
│    ├── User.java
│    ├── UserController.java
│    ├── UserRepository.java
│    └── UserService.java
│   // and everything else in the project
└── MyApplication.java

What would be a good approach, and what are the arguments to do so?

10
  • 6
  • 2
    I don't know @Laiv. Does the language/framework really affect the answer? Regardless, the other question is certainly relevant.
    – RubberDuck
    Dec 21, 2016 at 12:39
  • 1
    Then I have to edit my answer. And yest, it's a possible duplicate
    – Laiv
    Dec 21, 2016 at 12:41
  • 5
    I never understood the benefit of folder-by-type. If i'm working on a ticket pertaining to the Pet feature, I would probably benefit from locality of Pet, the controller, the repository, and the service. In what situation would I ever need all controllers, but non of the views, repos or services?
    – Alexander
    Dec 22, 2016 at 5:50
  • 2
    No one seems to have mentioned that packages in Java aren't just folders; they also affect access for the contained classes. For this reason, package-by-layer/type can actually provide some semantic value in Java. Dec 24, 2016 at 17:41

3 Answers 3

107

Folder-by-type only works on small-scale projects. Folder-by-feature is superior in the majority of cases.

Folder-by-type is ok when you only have a small number of files (under 10 per type, let's say). As soon as you get multiple components in your project, all with multiple files of the same type, it gets very hard to find the actual file you are looking for.

Therefore, folder-by-feature is better due to its scalability. However, if you use folder-by-feature, you end up losing information about the type of component a file represents (because it's no longer in a controller folder, let's say), so this too becomes confusing. There are 2 simple solutions for this.

First, you can abide by common naming conventions that imply its type in the file name. For example, John Papa's popular AngularJS style guide has the following:

Naming Guidelines

  • Use consistent names for all components following a pattern that describes the component's feature then (optionally) its type. My recommended pattern is feature.type.js. There are 2 names for most assets:

    • the file name (avengers.controller.js)
    • the registered component name with Angular (AvengersController)

Second, you can combine folder-by-type and folder-by-feature styles into folder-by-feature-by-type:

com.example
├── pet
|   ├── Controllers
│   |   ├── PetController1.java
|   |   └── PetController2.java
|   └── Services
│       ├── PetService1.java
│       └── PetService2.java
├── user
|   ├── Controllers
│   |   ├── UserController1.java
│   |   └── UserController2.java
|   └── Services
│       ├── UserService1.java
│       └── UserService2.java
10
  • 1
    The johnpapa style guide was exactly the one I was fakking about :-)
    – Jelle
    Dec 21, 2016 at 14:18
  • 1
    Some times (oftener than we think) we add too complexity to things that were supposed to be easy. Naming and packaging are some of these things. The best advice is keep it simple. Mixing both have either the advantages and the disadvantages of both approaches.
    – Laiv
    Dec 21, 2016 at 14:24
  • 1
    @Laiv In the example I gave I agree its overkill, but in most of my real business cases where each type-folder can easily have 10-20 files I think its very useful because the overall feature-folder would have on the order of 50 files otherwise. Dec 21, 2016 at 14:32
  • 9
    fakking, thanks iPhone auto-correct! I meant 'talking'.
    – Jelle
    Dec 21, 2016 at 14:56
  • 4
    @Chaotic This example is too trivial to start talking specifics, but in such cases where you have pieces that are used across multiple components, then that should probably be a component of its own that other components depend on. Dec 21, 2016 at 19:40
34

This really has nothing to do with the technology in question, unless you use a framework that forces folder-by-type on you as part of a convention-over-configuration approach.

Personally, I am strongly of the opinion, that folder-by-feature is far superior and should be used everywhere as much as possible. It groups together classes that actually work together, whereas folder-by-type just duplicates something that is usually already present in the class name.

3
  • 10
    I would add that in folder-by-feature makes easier to play with classes and methods scopes (protected, package,...).
    – Laiv
    Dec 21, 2016 at 11:37
  • 1
    For smaller projects you may only have one feature. It is much easier to organize by type in that scenario.
    – aaaaaa
    Dec 21, 2016 at 18:59
  • As an example, Grails does force folder-by-type for your domains, controllers, services, etc.
    – tylerwal
    Sep 19, 2018 at 12:13
29

Working with packages-by-feature stands out in high modularity and cohesion. It allows us to play with the components' scope. For example, we can use the access modifiers to enforce LoD and the dependency inversion for integrations or/and extensions.

Other reasons are:

  • Easier code navigation
  • A higher level of abstraction
  • Minimize scopes (bounding contexts)
  • Vertical modularization

Folder-by-layer puts too much emphasis on the implementation details, (as @David mentioned) which doesn't tells too much about the application we are working on. Unlike package-by-feature, package-by-layer encourage horizontal modularization. This sort of modularization makes working with cross-cutting components hard and tedious.

Finally, there's a 3rd option. Package by component which, in Uncle Bob's words, is aligned with his package principles. If Uncle's Bob opinion matters or not, I leave it to you to decide. I find it interesting since this convention is aligned with his Clean Architecture, which I like.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.