web-dev-qa-db-fra.com

Comment dois-je organiser mon arbre source?

Je suis un développeur individuel travaillant, en grande partie, sur des projets Web (W/LAMP) et, parfois, sur des projets C/C++ (non-GUI) d'une échelle à peu près moyenne.

J'ai souvent du mal à structurer mon arbre de code source. En fait, généralement, je ne termine pas un projet sans vider l'arbre entier et réorganiser les pièces trois à quatre fois, ce qui prend vraiment beaucoup d'efforts et, de plus, le résultat final semble être un compromis.

Parfois, je me retrouve avec une sur-classification de la source - très longue arborescence de dossiers et sous-dossiers. À d'autres moments, je finis simplement par concentrer tous les fichiers dans un dossier particulier en fonction de l'objectif plus large qu'ils servent et ainsi conduire à des dossiers "chaotiques" dans la source.

Je voudrais demander:

  • Existe-t-il des principes/logiques/meilleures pratiques qui peuvent m'aider à mieux structurer mon arbre source?
  • Existe-t-il des techniques graphiques/schématiques (par exemple: DFD en cas de flux de données) qui peuvent m'aider à visualiser mon arbre source au préalable sur la base de l'analyse du projet?
  • Quelle stratégie adopter pour structurer l'arborescence des fichiers multimédias associée au projet?

À propos de la prime: J'apprécie les réponses existantes avec les membres partageant leurs propres pratiques, cependant, je voudrais encourager des réponses (ou ressources) plus générales et instructives et plus de réponses des membres.

91
check123

La disposition de l'arborescence source doit refléter l'architecture; en corollaire, une architecture bien structurée peut conduire à une disposition d'arbre source bien structurée. Je suggère de lire le modèle de couches POSA1 , en essayant d'adapter votre architecture dans une structure en couches, puis en nommant chacune des couches résultantes et en l'utilisant comme base pour votre hiérarchie source. Prendre une architecture à trois niveaux commune comme référence:

  • presentation/webService (présenter une interface de service web à notre logique métier)
  • logique/* (les modules de logique métier vont ici)
  • storage/sql (API de stockage back-end ici - cela utilise une interface SQL pour stocker dans une base de données)
  • util/* (code utilitaire - utilisable par toutes les autres couches, mais qui ne fait pas référence à util extérieur, va ici)

Notez que les couches ne contiennent pas directement de code, mais sont plutôt strictement utilisées pour organiser les modules.

Dans un module, j'utilise le type de mise en page suivant:

  • <module> (chemin vers le module directement; définit l'interface modulaire)
  • <module>/impl/<implName> (une implémentation spécifique de l'interface modulaire)
  • <module>/doc (Documentation pour l'utilisation du module)
  • <module>/tb (code de test unitaire pour le module)

où le <module> est situé dans le référentiel en fonction de la couche à laquelle il appartient.

25
Aidan Cully

Je ne peux pas vraiment vous donner beaucoup de conseils sur les projets Web, mais voici comment je structure mon arbre dans un projet de programmation (principalement du point de vue C/C++):

  • /
    • src - Fichiers source écrits par moi-même
    • ext - Contient des bibliothèques tierces
      • libname-1.2.8
        • inclure - En-têtes
        • lib - Fichiers lib compilés
        • Donwload.txt - Contient un lien pour télécharger la version utilisée
    • ide - Je stocke les fichiers de projet ici
      • vc1 - J'organise les fichiers de projet en fonction de l'IDE
    • bin - L'exe compilé va ici
    • build - Les fichiers de compilation du compilateur
    • doc - Documentation de toute nature
    • README
    • INSTALLER
    • COPIER

Quelques notes:

  1. Si j'écris une bibliothèque (et j'utilise C/C++), je vais d'abord organiser mes fichiers source dans deux dossiers appelés "include" et "src" puis par module. Si c'est une application, je vais les organiser juste par module (les en-têtes et les sources iront dans le même dossier).

  2. Fichiers et répertoires que j'ai énumérés ci-dessus dans italique Je n'ajouterai pas au référentiel de code.

49
Paul

Alors que le Maven Standard Directory Layout est spécifique à Java, mais il peut également servir de bonne base pour d'autres types de projets.

Voici la structure de base (vous pouvez remplacer les répertoires 'Java' par 'php', 'cpp', etc):

src/main/Java       Application/Library sources 
src/main/resources  Application/Library resources  
src/main/filters    Resource filter files 
src/main/Assembly   Assembly descriptors 
src/main/config     Configuration files 
src/main/webapp     Web application sources 
src/test/Java       Test sources 
src/test/resources  Test resources 
src/test/filters    Test resource filter files 
src/site            Site 
LICENSE.txt         Project's license 
NOTICE.txt          Notices and attributions required by libraries
README.txt          Project's readme

La structure se décompose fondamentalement en "src/main" et "src/test", puis regroupée par type.

15
Michal Miller

Idéalement, l'organisation dispose d'un référentiel unique, dont la structure est destinée à accroître l'engagement entre l'ingénierie et les affaires et à promouvoir la réutilisation.

...\products\
...\products\productName\
...\products\productName\doc\

...\systems\
...\systems\systemName\
...\systems\systemName\doc\
...\systems\systemName\res\
...\systems\systemName\build\
...\systems\systemName\test\

...\library\
...\library\libraryName\
...\library\libraryName\doc\
...\library\libraryName\build\
...\library\libraryName\test\

...\devops\

produits

Un dossier par produit; aide à communiquer comment le logiciel prend en charge l'entreprise.

Idéalement, chaque "produit" n'est guère plus qu'un fichier de configuration indiquant quels systèmes invoquer et comment ils doivent être configurés. Le sous-dossier doc peut contenir le brief\spec de haut niveau et tout matériel promotionnel etc ...

En séparant les produits et les systèmes, nous communiquons le potentiel de réutilisation au côté client de l'entreprise, et brisons les silos par produit. (Cela contraste avec l'approche "gamme de produits" du même problème)

systèmes

Un dossier par système; aide à communiquer les capacités principales et l'opportunité/la valeur du contenu du référentiel.

  1. Fichiers "Gestion de la configuration" spécifiant les environnements de construction et de déploiement.
  2. Configuration de test au niveau du système (peut être une quantité importante).
  3. Logique et fonctionnalité de haut niveau; la plupart des opérations de levage sont effectuées par les fonctions de bibliothèque.

bibliothèque

Composants réutilisables invoqués par divers systèmes. La plupart des activités de développement sont organisées autour de la production de bibliothèques, plutôt que de systèmes, de sorte que la réutilisation est "intégrée" au processus de développement.

devops

Build, intégration continue et autres fonctionnalités d'automatisation du développement.

Conclusion

L'arbre source est un élément clé de la documentation et façonne l'approche, la structure et la psychologie de la relation de l'entreprise avec sa technologie propriétaire.

Les pilotes de cette approche sont expliqués un peu plus en profondeur dans ma réponse à cette question: https://softwareengineering.stackexchange.com/questions/43733/who-organizes-your-matlab-code/59637#59637

6
William Payne

Je ne connais pas vraiment les conventions mais tous mes projets principaux sont réalisés en utilisant Symfony Framework et je me suis habitué à une structure arborescente comme suit:

racine/

  • applications
  • nom de l'application
    • config (fichiers de configuration spécifiques à l'application)
    • lib (fichiers php spécifiques à l'application)
    • modules (distribution modulaire des fonctionnalités)
      • nom_module
        • modèles (html)
        • actions (code php)
  • confing (fichiers de configuration du projet)
  • lib (code php qui pourrait être utilisé dans le projet de trou)
  • modèle (classes qui représentent les informations du projet)
    • base
  • form (fichiers php qui gèrent les formulaires, cela pourrait être assez difficile à réaliser sans symfony)
    • base (classes de formulaire de base)
  • web
  • css
    • images
    • file.css
  • js
  • journal (fichiers journaux pouvant être générés)
  • données (informations spécifiques aux données, comme les correctifs SQL, ou autre)
  • sql
  • plugins (bibliothèques utilisées pouvant être fusionnées avec n'importe quelle application du projet)

Si vous êtes intéressé, veuillez lire la documentation de symfony à ce sujet pour plus d'informations ( MVC et organisation du code sur Symfony ).

5
guiman

Ce que j'essaie de faire pour chaque projet est similaire à:

  • src - fichiers source, un dossier pour chaque espace de noms/package pour récupérer facilement les fichiers (même les fichiers d'en-tête pour C/C++)
  • ext - pour les bibliothèques externes/tierces, il est simple d'ajouter des ressources externes (telles que les référentiels SVN). A l'intérieur, un dossier pour chaque bibliothèque (binaires et fichiers inclus)
  • bin - pour les binaires construits, pourrait être rapidement exporté pour publication
    • inc - pour le fichier d'en-têtes C/C++ (copié par IDE/makefile/etc ...)
  • out - pour tous les fichiers générés temporairement (.class, .obj etc ...) et il pourrait être ignoré (par exemple par SVN)
  • doc - pour toute documentation, généralement générée avec Doxygen
  • res - en plaçant des ressources ici, il est possible de séparer les fichiers sources de texte et les ressources binaires utilisées par le programme. Je n'ai pas vraiment de hiérarchie spécifique à l'intérieur.
    • config - pour certains fichiers de configuration
    • dessinable - pour certaines images ou icônes

Tous les fichiers ou makefiles de l'EDI sont enregistrés directement à la racine si vous n'en utilisez qu'un seul.

3
Ninfomane

Je fais quelque chose comme ça. Fonctionne bien pour un jeu multiplateforme que je fais pendant mon temps libre. Malheureusement au travail, les choses sont beaucoup moins organisées ...

Output                      <-- Build outputs
Docs
External
   <libname>
      Include
      Lib
Data
<ProjectName>.xcodeproj
<ProjectName>VS2010
Source
Temp                        <-- Intermediate stuff from builds and other tools
Tools
2
Colonel Panic

J'aime les idées présentées dans cette page www.javapractices.com/topic/TopicAction.do?Id=205 . Fondamentalement, la recommandation est d'organiser votre projet en fonctionnalités (ou modules, composants). En plus des raisons qui y sont présentées:

  1. Moins de charge cognitive lorsque vous pensez à la portée du code sur lequel vous travaillez, car vous avez la garantie que tout code de la fonctionnalité sur laquelle vous travaillez est "privé de fonctionnalité".
  2. Il y a un sentiment de sécurité supplémentaire lorsque vous êtes assuré de ne modifier le code que pour une fonction donnée. Par exemple, vous ne casserez rien d'autre que la fonctionnalité sur laquelle vous travaillez. Encore une fois, c'est à cause de la "fonctionnalité privée".
  3. Moins de charge cognitive simple car il y a moins de fichiers que vous pouvez voir pour un package donné. Je suis sûr que tout le monde a vu un paquet contenant plus de 15 fichiers.

Notez que cela se concentre sur Java packages (aka namespaces). Pour les grands projets, je recommande, pour les mêmes raisons, de diviser le projet en plusieurs projets (comme dans plusieurs projets maven) qui représente un pour les projets maven, je recommande ceci lecture .

Jusqu'à présent, les projets dans lesquels j'ai été/suis impliqué ne suivent pas ceux-ci. Il y a plusieurs raisons, mais en voici quelques-unes:

  1. Le malentendu de Java modificateur d'accès par défaut (le modificateur d'accès le plus mal compris selon ceci livre )
  2. "Argumentum ad populum": Culture dominante du package par couche (probablement causée par la Raison n ° 1)

Je pense qu'il y a une occasion manquée d'empêcher la complexité si l'organisation de la source du projet n'est pas prise au sérieux au début du projet, comme l'a dit l'architecte Alexander:

"Comme tout designer vous le dira, ce sont les premières étapes d'un processus de conception qui comptent le plus. Les premiers traits, qui créent la forme, portent en eux le destin du reste." - Christopher Alexander

Selon la taille et la complexité d'un projet, l'opportunité manquée de réduire les coûts ou le retour sur investissement peut être très importante. (Je suis intéressé de voir une étude pour voir les chiffres exacts pour cela)

2
thirdy

Pour mes équipes, nous essayons d'appliquer une structure standard à travers les projets afin de faciliter la recherche de choses au fur et à mesure que l'équipe change de contexte et d'éviter d'avoir à réapprendre à chaque fois. Tous les projets n'ont pas besoin de tous les systèmes, nous commençons donc avec l'ensemble minimal.

/ Source/Composant/Langue

/ Source/Composant/Tierce partie /

/ Documentation/Exigences

/ Documentation/Conception

/ Tests/Automatisé/Unité

/ Tests/Automatisé/ToolName

/ Tests/Manuel

Cela entraîne une certaine duplication, en particulier sous le code et les bibliothèques tiers, mais au moins nous n'oublions jamais la réponse à quelque chose comme "Qu'est-ce qui utilise l'éditeur RogueWave?"

2
Christopher Bibbs

Ma recommandation est de télécharger une variété de cadres ou de moteurs et de voir comment les énormes équipes de développement ont géré la disposition de leurs dossiers.

Il y a tellement de façons d'organiser les fichiers qu'il vaut mieux en choisir un et essayer de s'y tenir à n'importe quel projet donné. Respectez une convention particulière jusqu'à la fin ou la refonte pour éviter les bugs et perdre du temps inutile.

Vous pouvez télécharger les frameworks Laravel, Symphony ou Codeigniter pour les projets Web afin d'avoir une disposition de dossier instantanée qui fonctionne.

Je vais donc essayer de transmettre une disposition de dossiers commune à tout développement:

MVC (Model View Controller) donne un bon paradigme d'organisation.

Le code source racine pourrait être src (C++) ou app (développement web)

Une structure de fichiers qui n'a pas d'objectif clair pour les classes qu'elle regroupe provoquera certainement de la confusion. Il ne s'agit pas seulement d'organiser du code, mais de soutenir des chargeurs automatiques, une fabrique de classes, un stockage local, un stockage à distance et un espace de noms.

Cette structure de dossiers est dérivée et simplifiée de Laravel Framework. Ma préférence pour ce poste est la dénomination plurielle mais j'utilise des mots singuliers dans mes projets.


src/stockage (implémentations models/file-storage/api/mysql/sql-lite/memcached/redis)

src/repositories (Un wrapper de "mises en œuvre de stockage" avec une logique de stockage, une interface commune et une convention de résultat de retour.)

src/services | logique | entités (logique bussiness d'application)

src/controllers (Utilisé sur le développement Web pour acheminer les requêtes du serveur vers vos services)

src/modules | systems (Systèmes modulaires qui étendent les fonctionnalités générales de votre framework. Les services peuvent utiliser des modules mais pas vice versa)

src/helpers (classes d'assistance ou d'encapsulation comme par exemple la manipulation de chaînes. Plusieurs fois, cela pourrait être sur libs | vendor quand un tiers)

src/types (énumérations nommées)

public | build | output (web ou c ++)

config (Fichiers d'installation. YAML devient populaire pour les fichiers de configuration multiplateforme)

cache

journaux

lang (en/es/ru/...)

bootstrap (Démarre le framework et l'application)

docs (Documentation écrite au format markdown .md)

tests (tests unitaires)

base de données/migrations (Créer une structure de base de données à partir de zéro)

base de données/graines (Remplit votre base de données avec des données factices à tester)

libs | vendor (tous les logiciels tiers. 'libs' sur C++ et 'vendor' habituellement sur php)

actifs | ressources (images/sons/scripts/json/tout média)

2
Heroselohim

Avec les langages orientés objet, vous avez la possibilité de créer des espaces de noms. Cette ventilation logique utilisée pour séparer les parties de l'application pour éviter le couplage est la principale source de panne de l'emplacement du fichier logique. L'utilisation du couplage comme raison de la séparation des espaces de noms est un bon point de départ http://en.wikipedia.org/wiki/Software_package_metrics .

D'autres ont parlé de la mise en place du projet par rapport à la construction, mais une fois que vous entrez dans la source elle-même, c'est ce qui a du sens - utilisez simplement la façon dont vous séparez logiquement le code de toute façon.

1
Travis