web-dev-qa-db-fra.com

Dossier par type ou Dossier par fonctionnalité

J'utilise un guide de style AngularJS. Dans ce guide, il existe un style appelé folder-by-feature, au lieu de folder-by-type, et je suis en fait curieux de savoir quelle est la meilleure approche (dans cet exemple pour Java)

Disons que j'ai une application où je peux récupérer des utilisateurs et des animaux de compagnie, en utilisant des services, des contrôleurs, des référentiels et des objets de domaine ofcourse.

En prenant les styles de dossier par -....., nous avons deux options pour notre structure d'emballage:

1. Dossier par 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. Dossier par fonction

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

Quelle serait une bonne approche et quels sont les arguments pour le faire?

63
Jelle

Le dossier par type ne fonctionne que sur les projets à petite échelle. Le dossier par fonction est supérieur dans la majorité des cas.

Le dossier par type est correct lorsque vous n'avez qu'un petit nombre de fichiers (moins de 10 par type, disons). Dès que vous obtenez plusieurs composants dans votre projet, tous avec plusieurs fichiers du même type, il devient très difficile de trouver le fichier réel que vous recherchez.

Par conséquent, le dossier par fonctionnalité est meilleur en raison de son évolutivité. Cependant, si vous effectuez un dossier par fonctionnalité, vous finissez par perdre des informations sur le type de composant représenté par un fichier (car ce n'est plus dans un dossier controller, disons), cela devient donc aussi déroutant. Il existe 2 solutions simples pour cela.

Tout d'abord, vous pouvez respecter les conventions de dénomination courantes qui impliquent la typicité du nom de fichier. Par exemple, le populaire guide de style AngularJS de John Papa présente les éléments suivants:

Consignes de dénomination

  • Utilisez des noms cohérents pour tous les composants en suivant un modèle qui décrit la fonction du composant puis (éventuellement) son type. ma
    le modèle recommandé est feature.type.js. Il y a 2 noms pour la plupart
    les atouts:

    • le nom du fichier (avengers.controller.js)
    • le nom du composant enregistré avec Angular (AvengersController)

Deuxièmement, vous pouvez combiner des styles de dossier par type et de dossier par fonction en dossier par fonction par 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

Cela n'a vraiment rien à voir avec la technologie en question, à moins que vous n'utilisiez un cadre qui vous impose un dossier par type dans le cadre d'une approche de convention sur configuration.

Personnellement, je suis fermement d'avis que ce dossier par fonctionnalité est de loin supérieur et devrait être utilisé partout autant que possible. Il regroupe les classes qui fonctionnent réellement ensemble, tandis que le dossier par type duplique simplement quelque chose qui est généralement déjà présent dans le nom de la classe.

26
Michael Borgwardt

Travailler avec packages-by-feature se distingue par une grande modularité et cohésion . Cela nous permet de jouer avec la portée des composants. Par exemple, nous pouvons utiliser modificateurs d'accès pour appliquer LoD et inversion de dépendance pour les intégrations ou/et les extensions.

D'autres raisons sont:

  • Navigation de code plus facile
  • Un niveau d'abstraction plus élevé
  • Minimiser les portées (contextes englobants)
  • Modularisation verticale

Folder-by-layer met trop d'accent sur les détails d'implémentation , (comme @David l'a mentionné) ce qui ne dit pas trop sur l'application sur laquelle nous travaillons . Contrairement à package-by-feature, package-by-layer encourage la modularisation horizontale. Ce type de modularisation rend le travail avec des composants transversaux difficile et fastidieux.

Enfin, il existe une troisième option. " Package par composant " qui, selon les mots de l'oncle Bob, semble mieux aligné avec ses principes du package . Si l'opinion de Bob de l'oncle est importante ou non, je vous laisse le soin de décider. Je trouve cela intéressant car cette convention est alignée sur son architecture propre, que j'aime.

17
Laiv