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:
À 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.
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:
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.
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++):
Quelques notes:
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).
Fichiers et répertoires que j'ai énumérés ci-dessus dans italique Je n'ajouterai pas au référentiel de code.
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.
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.
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
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/
Si vous êtes intéressé, veuillez lire la documentation de symfony à ce sujet pour plus d'informations ( MVC et organisation du code sur Symfony ).
Ce que j'essaie de faire pour chaque projet est similaire à:
Tous les fichiers ou makefiles de l'EDI sont enregistrés directement à la racine si vous n'en utilisez qu'un seul.
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
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:
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:
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)
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?"
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)
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.