Wie soll ich meinen Source Tree organisieren?

89

Ich bin ein einzelner Entwickler und arbeite hauptsächlich an Web-Projekten (W / LAMP) und manchmal an C / C ++ (Nicht-GUI) -Projekten von ungefähr durchschnittlichem Umfang.

Ich habe oft Probleme mit der Strukturierung meines Quelltextbaums. Normalerweise schließe ich ein Projekt nicht ab, ohne den gesamten Baum zu entleeren und die Teile drei- bis viermal neu anzuordnen, was wirklich viel Aufwand bedeutet und außerdem scheint das Endergebnis ein Kompromiss zu sein.

Manchmal ende ich mit einer Überklassifizierung der Quelle - einem sehr langen Baum von Ordnern und Unterordnern. In anderen Fällen konzentriere ich einfach alle Dateien in einem bestimmten Ordner, basierend auf dem Zweck, den sie erfüllen, und führe dadurch zu „chaotischen“ Ordnern in der Quelle.

Ich würde fragen wollen:

  • Gibt es Prinzipien / Logik / Best Practices, die mir bei der Strukturierung meines Quellbaums helfen können?
  • Gibt es grafische / diagrammatische Techniken (zum Beispiel DFD bei Datenfluss), die mir helfen können, meinen Quellbaum auf der Grundlage der Analyse des Projekts im Voraus zu visualisieren?
  • Welche Strategie zur Strukturierung des mit dem Projekt verbundenen Multimedia-Dateibaums ist anzuwenden?

Über das Kopfgeld : Ich schätze die vorhandenen Antworten der Mitglieder, die ihre eigenen Praktiken teilen. Ich möchte jedoch allgemeinere und aufschlussreichere Antworten (oder Ressourcen) und mehr Antworten der Mitglieder ermutigen.

check123
quelle
8
Ich habe momentan keine Zeit für einen Aufsatz, aber "benenne die Dinge so, wie sie sind", "setze die Dinge dort, wo sie hingehören", "halte ähnliche Dinge nahe beieinander" und schließlich "sorge dich nicht darum , Sie haben hoffentlich eine IDE, mit der Sie schnell zwischen den Codeteilen navigieren können ".
John Saunders
@ John, ich bin nicht so gut mit IDE (s), ich ziehe im Allgemeinen ein Notepad ++ oder vi, je nach Betriebssystem. Das macht die Sache etwas schwieriger. Der Rest der Punkte ist hilfreich, aber auch hier kommt es darauf an, knifflige Entscheidungen zu treffen, wie z. B. Protokollfunktionen (Fehlerprotokolle usw.), die der Anwendungslogik oder der DAL- oder Cache-Verwaltung oder den Ansichtsmanagern näher kommen. Fehler treten fast mit der gleichen Wahrscheinlichkeit auf.
check123
3
Vielleicht ist es an der Zeit, einige Tools einen Teil der Arbeit für Sie erledigen zu lassen, wenn Sie diese Art von Frage haben. Die Protokollierung ist eindeutig ein funktionsübergreifendes Problem, das von allen Teilen der Anwendung verwendet wird (wenn Sie die Art von Code verwenden, die protokolliert werden muss). Ein weiteres kleines Sprichwort lautet: "Setzen Sie den Code über den Code, der ihn verwendet". Die Protokollierung sollte sich also ganz oben befinden, möglicherweise in \ utilities.
John Saunders
@ John: Sehr geschätzt. Vielleicht sollte ich nach einer IDE suchen. Eclipse scheint vielversprechend.
check123
1
@ check123 "... die Teile drei- bis viermal neu anordnen ..." Übliche Praxis: "Die Managementfrage lautet daher nicht, ob ein Pilotsystem gebaut und weggeworfen werden soll. Das wirst du machen. Die einzige Frage ist , ob im Voraus zu planen , eine Wegwerf zu bauen, oder die Wegwerf an Kunden zu liefern verspricht „- Frederick P. Brooks Jr., The Mythical Man-Month. Essays on Software Engineering
shawnhcorey

Antworten:

25

Das Layout des Quellbaums sollte die Architektur widerspiegeln. als folge kann eine gut strukturierte architektur zu einem gut strukturierten quellbaumlayout führen. Ich empfehle, das POSA1-Ebenenmuster nachzulesen , zu versuchen, Ihre Architektur in eine Ebenenstruktur einzufügen , dann jede der resultierenden Ebenen zu benennen und dies als Grundlage für Ihre Quellhierarchie zu verwenden. Eine gemeinsame dreistufige Architektur als Basis nehmen:

  • presentation / webService (präsentiert eine Web-Service-Schnittstelle zu unserer Geschäftslogik)
  • logic / * (Geschäftslogikmodule gehen hier rein)
  • storage / sql (Back-End-Speicher-APIs hier - verwendet eine SQL-Schnittstelle zum Speichern in einer Datenbank)
  • util / * (Utility-Code - kann von allen anderen Layern verwendet werden, bezieht sich aber nicht außerhalb von util, siehe hier)

Beachten Sie, dass die Ebenen keinen direkten Code enthalten, sondern ausschließlich zum Organisieren von Modulen verwendet werden.

Innerhalb eines Moduls verwende ich das folgende Layout:

  • <module> (Pfad zum Modul direkt; definiert modulare Schnittstelle)
  • <module>/impl/<implName> (eine spezifische Implementierung der modularen Schnittstelle)
  • <module>/doc (Dokumentation zur Benutzung des Moduls)
  • <module>/tb (Unit-Test-Code für das Modul)

Wo sich das <module>im Repository befindet, richtet sich nach der Ebene, zu der es gehört.

Aidan Cully
quelle
5
+1: Das Layout des Quellbaums sollte die Architektur widerspiegeln - eine offensichtliche Sache, die ich übersah.
check123
Wie verwalten Sie sichere Dateien - Dateien, auf die nur autorisierte Benutzer nach der Anmeldung zugreifen können?
check123
@check123 Ich bin mir nicht sicher, ob ich die Frage verstehe. Ich habe mich auf die Organisation von Quellmodulen konzentriert, anstatt Dateien für das Projekt zu unterstützen, und der Quellcode soll normalerweise für alle zugänglich sein. (Es gibt Ausnahmen, und ich verwende ein dist / -Verzeichnis vor allem mit nicht standardmäßigen Verwendungs- / Änderungsbeschränkungen.)
Aidan Cully
48

Ich kann Ihnen in Bezug auf Webprojekte nicht wirklich viele Ratschläge geben, aber so strukturiere ich meinen Baum in einem Programmierprojekt (hauptsächlich aus einer C / C ++ - Perspektive):

  • /
    • src - Von mir selbst geschriebene Quelldateien
    • ext - Enthält Bibliotheken von Drittanbietern
      • libname-1.2.8
        • include - Überschriften
        • lib - Kompilierte lib-Dateien
        • Donwload.txt - Enthält einen Link zum Herunterladen der verwendeten Version
    • ide - Ich speichere hier Projektdateien
      • vc10 - Ich ordne Projektdateien abhängig von der IDE an
    • bin - Kompilierte exe geht hier
    • build - Die Build-Dateien des Compilers
    • doc - Dokumentation jeglicher Art
    • Liesmich
    • INSTALLIEREN
    • KOPIEREN

Ein paar Anmerkungen:

  1. Wenn ich eine Bibliothek schreibe (und C / C ++ verwende), organisiere ich meine Quelldateien zuerst in zwei Ordnern mit den Namen "include" und "src" und dann nach Modul. Wenn es sich um eine Anwendung handelt, ordne ich sie nach Modulen (Überschriften und Quellen befinden sich im selben Ordner).

  2. Dateien und Verzeichnisse, die ich oben in Kursivschrift aufgeführt habe, werden dem Code-Repository nicht hinzugefügt.

Paul
quelle
Was ist der Unterschied zwischen ide und build ?
M. Dudley
3
ideist nur, wo ich die Projektdateien selbst speichere. buildenthält die vom Compiler erzeugten Objektdateien. Verschiedene IDEs können den gleichen Compiler verwenden. Deshalb trenne ich die IDE-Projektdateien von den vom Compiler erstellten Objektdateien.
Paul
also build == obj (der Begriff, der von vielen anderen Systemen verwendet wird)
gbjbaanb
@ gbjbaanb Ja, ich denke. Es spielt keine Rolle, da dieses Verzeichnis nicht in das Repository verschoben wird. :) Ich habe es 'build' genannt, weil die von mir verwendete IDE att es (Visual Studio) nannte.
Paul
Was ist, wenn Ihre Exe eine DLL benötigt, um zu laufen? Kopieren Sie alle DLL-Dateien in dasselbe Verzeichnis wie exe? Verwenden Sie einige Ereignisse nach dem Erstellen?
Wakan Tanka
14

Das Maven Standard Directory Layout ist zwar spezifisch für Java, kann aber auch als gute Grundlage für andere Projekttypen dienen.

Hier ist die Grundstruktur (Sie könnten die 'Java'-Verzeichnisse durch' PHP ',' CPP 'usw. ersetzen):

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

Die Struktur gliedert sich grundsätzlich in 'src / main' und 'src / test', die dann nach Typ gruppiert werden.

Michal Miller
quelle
5

Ich kenne mich mit Konventionen nicht wirklich aus, aber alle meine Hauptprojekte werden mit Symfony Framework durchgeführt und ich habe mich an eine Baumstruktur wie die folgende gewöhnt:

Wurzel/

  • Apps
  • App Name
    • config (app-spezifische Konfigurationsdateien)
    • lib (App-spezifische PHP-Dateien)
    • Module (modulare Funktionsverteilung)
      • Modulname
        • Vorlagen (html)
        • Aktionen (PHP-Code)
  • confing (Projektkonfigurationsdateien)
  • lib (PHP-Code, der in einem ganzen Projekt verwendet werden könnte)
  • Modell (Klassen, die die Projektinformationen darstellen)
    • Base
  • form (PHP-Dateien, die mit Formularen umgehen, dies könnte ohne symfony ziemlich schwierig zu erreichen sein)
    • base (Grundformklassen)
  • Netz
  • CSS
    • bilder
    • file.css
  • js
  • log (Logdateien, die generiert werden könnten)
  • Daten (datenspezifische Informationen, wie SQL-Patches oder was auch immer)
  • sql
  • Plugins (verwendete Bibliotheken, die mit jeder App des Projekts zusammengeführt werden können)

Wenn Sie interessiert sind, lesen Sie bitte die Symfony-Dokumentation zu diesem Thema, um weitere Informationen zu erhalten ( MVC und Code Organization on Symfony ).

Guiman
quelle
Ist Ihr CSS-Ordner zentralisiert? Ich meine, alle Ihre CSS (über das Projekt) sind im gleichen Verzeichnis?
check123
Nicht unbedingt, Sie könnten es teilen, aber da die meisten meiner Projekte nur 2 Apps (Frontend und Backend) haben, gibt es nicht so viele CSS-Dateien (Plugins haben immer einen eigenen
Webordner
5

Idealerweise verfügt die Organisation über ein einziges Repository, dessen Struktur darauf abzielt, die Zusammenarbeit zwischen Engineering und Business zu verbessern und die Wiederverwendung zu fördern.

...\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\

Produkte

Ein Ordner pro Produkt; Hilft zu kommunizieren, wie die Software das Geschäft unterstützt.

Im Idealfall ist jedes "Produkt" nur eine Konfigurationsdatei, die angibt, welche Systeme aufgerufen und wie sie konfiguriert werden sollen. Der doc-Unterordner kann die Kurzbeschreibung auf oberster Ebene und Werbematerialien usw. enthalten.

Durch die Trennung von Produkten und Systemen kommunizieren wir das Potenzial der Wiederverwendung an die kundenorientierte Seite des Geschäfts und bauen Silos pro Produkt auf. (Dies steht im Gegensatz zum "Produktlinien" -Ansatz für dasselbe Problem.)

systeme

Ein Ordner pro System; Hilft bei der Vermittlung der wichtigsten Funktionen und Möglichkeiten / des Werts des Inhalts des Repository.

  1. "Konfigurationsmanagement" -Dateien, die Build- und Bereitstellungsumgebungen angeben.
  2. Testkonfiguration auf Systemebene (kann eine erhebliche Menge sein).
  3. Logik & Funktionalität auf höchstem Niveau; das meiste schwere Heben wird durch Bibliotheksfunktionen ausgeführt.

Bibliothek

Wiederverwendbare Komponenten, die von verschiedenen Systemen aufgerufen werden. Die meisten Entwicklungsaktivitäten sind eher auf die Produktion von Bibliotheken als auf Systeme ausgerichtet, sodass die Wiederverwendung in den Entwicklungsprozess "eingebrannt" wird.

Devops

Build, Continuous Integration und andere Funktionen der Entwicklungsautomatisierung.

Fazit

Der Quellenbaum ist ein zentrales Dokumentationselement und bestimmt den Ansatz, die Struktur und die Psychologie der Geschäftsbeziehung mit seiner proprietären Technologie.

Die Treiber für diesen Ansatz werden in meiner Antwort auf diese Frage etwas ausführlicher erläutert: https://softwareengineering.stackexchange.com/questions/43733/who-organizes-your-matlab-code/59637#59637

William Payne
quelle
Hinweis: Es kann nützlich sein, Ordner so zu benennen, dass sie mit der Art der Produkthierarchien kompatibel sind, die im INCOSE Systems Engineering-Handbuch beschrieben werden.
William Payne
3

Was ich versuche, für jedes Projekt zu tun, ist ähnlich wie:

  • src - Quelldateien, ein Ordner für jeden Namespace / jedes Paket zum einfachen Abrufen von Dateien (auch Header-Dateien für C / C ++)
  • ext - Für externe Bibliotheken / Bibliotheken von Drittanbietern ist es einfach, externe Bibliotheken (z. B. SVN-Repositorys) hinzuzufügen. Innerhalb eines Ordners für jede Bibliothek (Binärdateien und Include-Dateien)
  • bin - für erstellte Binärdateien, konnte zur Veröffentlichung schnell exportiert werden
    • inc - für C / C ++ Header-Datei (kopiert von IDE / makefile / etc ...)
  • out - für alle temporär erzeugten Dateien (.class, .obj etc ...) und es könnte ignoriert werden (zum Beispiel von SVN)
  • doc - für jede Dokumentation, die normalerweise mit Doxygen erstellt wird
  • res - Durch das Platzieren von Ressourcen ist es möglich, vom Programm verwendete Textquelldateien und Binärressourcen zu trennen. Ich habe keine spezifische Hierarchie im Inneren.
    • config - für einige Konfigurationsdateien
    • Zeichenbar - für einige Bilder oder Icons

Alle IDE-Dateien oder Makefiles werden direkt im Stammverzeichnis gespeichert, wenn Sie nur eine davon verwenden.

Ninfomane
quelle
2

Ich mache so etwas. Funktioniert gut für ein plattformübergreifendes Spiel, das ich in meiner Freizeit mache. Leider sind die Dinge in der Arbeit viel weniger organisiert ...

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

Für meine Teams versuchen wir, eine projektübergreifende Standardstruktur zu erzwingen, damit es einfach ist, Dinge zu finden, wenn das Team den Kontext wechselt, und zu vermeiden, jedes Mal neu lernen zu müssen. Nicht für alle Projekte sind alle Systeme erforderlich, daher beginnen wir mit der minimalen Menge.

/ Quelle / Komponente / Sprache

/ Quelle / Komponente / Drittanbieter /

/Dokumentationsanforderungen

/ Dokumentation / Gestaltung

/ Tests / Automatisiert / Einheit

/ Tests / Automated / ToolName

/ Tests / Handbuch

Dies führt zu einigen Vervielfältigungen, insbesondere unter dem Code und den Bibliotheken von Drittanbietern, aber zumindest vergessen wir nie die Antwort auf etwas wie "Was verwendet der RogueWave-Editor?".

Christopher Bibbs
quelle
1
Großgeschriebene Pfadkomponenten sehen für mich wirklich albern und sinnlos aus. Warum viel Kleinbuchstaben? Das ist für den Menschen so viel einfacher zu tippen (obwohl es die Tools, einschließlich der WIMP- Dateimanager, nicht interessieren ) und kann dank der Pfadtrennzeichen genauso gut gelesen werden. Ein definitiver Gewinn für mich.
ulidtko
2

Mir gefallen die Ideen auf dieser Seite www.javapractices.com/topic/TopicAction.do?Id=205 . Grundsätzlich empfiehlt es sich, Ihr Projekt in Features (oder Module, Komponenten) zu organisieren. Zusätzlich zu den dort aufgeführten Gründen:

  1. Weniger kognitive Belastung, wenn Sie über den Umfang des Codes nachdenken, an dem Sie arbeiten, da Sie die Garantie haben, dass jeder Code in der Funktion, an der Sie arbeiten, "feature-private" ist.
  2. Es gibt ein zusätzliches Sicherheitsgefühl, wenn garantiert wird, dass Sie nur Code für eine bestimmte Funktion ändern. Sie brechen beispielsweise nichts anderes als die Funktion, an der Sie arbeiten. Auch dies liegt am "feature-private".
  3. Weniger kognitive Belastung einfach, da für ein bestimmtes Paket weniger Dateien angezeigt werden. Ich bin sicher, jeder hat ein Paket gesehen, das mehr als 15 Dateien enthält.

Beachten Sie, dass dies auf Java-Pakete (auch bekannt als Namespaces) ausgerichtet ist. Für große Projekte empfehle ich aus den gleichen Gründen, das Projekt in mehrere Projekte (wie in mehreren Maven-Projekten) zu unterteilen, die eine Geschäftsfunktion darstellen. Für Maven-Projekte empfehle ich diese Lektüre .

Bisher folgen die Projekte, an denen ich beteiligt war / bin, diesen nicht. Es gibt viele Gründe, aber hier sind einige:

  1. Das Missverständnis des Java-Standardzugriffsmodifikators (der am häufigsten missverstandene Zugriffsmodifikator gemäß diesem Buch )
  2. "Argumentum ad populum": Die vorherrschende Kultur von Paketen nach Schichten (wahrscheinlich verursacht durch Grund 1)

Ich denke, es gibt eine verpasste Möglichkeit, Komplexität zu vermeiden, wenn die Organisation der Projektquellen zu Beginn des Projekts nicht ernst genommen wird, wie der Architekt Alexander sagte:

"Wie jeder Designer Ihnen sagen wird, sind es die ersten Schritte in einem Designprozess, die am meisten zählen. Die ersten paar Striche, die die Form erzeugen, tragen das Schicksal der anderen in sich." - Christopher Alexander

Abhängig von der Größe und Komplexität eines Projekts kann die verpasste Möglichkeit, Kosten oder Kapitalrendite zu senken, sehr groß sein. (Ich bin daran interessiert, eine Studie zu sehen, um die genauen Zahlen dafür zu sehen.)

drittens
quelle
2

Ich empfehle, verschiedene Frameworks oder Engines herunterzuladen und zu sehen, wie große Entwicklungsteams mit dem Layout ihrer Ordner umgegangen sind.

Es gibt so viele Möglichkeiten, Dateien zu organisieren, dass es besser ist, eine auszuwählen und bei einem bestimmten Projekt zu bleiben. Halten Sie sich bis zur Fertigstellung oder Überarbeitung an eine bestimmte Konvention, um Fehler zu vermeiden und unnötige Zeit zu verlieren.

Sie können Laravel-, Symphony- oder Codeigniter-Frameworks für Webprojekte herunterladen, um ein sofortiges Ordnerlayout zu erhalten, das funktioniert.

Deshalb werde ich versuchen, ein Ordnerlayout zu vermitteln, das jeder Entwicklung gemein ist:

MVC (Model View Controller) bietet ein gutes Organisationsparadigma.

Root-Quellcode könnte src (C ++) oder app (Webentwicklung) sein

Eine Dateistruktur, die kein klares Ziel für die von ihr gruppierten Klassen hat, führt definitiv zu Verwirrung. Es dient nicht nur zum Organisieren von Code, sondern kann auch Auto-Loader, Class Factory, Wrap Local Storage, Remote Storage und Namespacing unterstützen.

Diese Ordnerstruktur ist vom Laravel Framework abgeleitet und vereinfacht . Ich bevorzuge in diesem Beitrag die Pluralbenennung, verwende jedoch in meinen Projekten einzelne Wörter.


src / storage (Implementierungen von models / file-storage / api / mysql / sql-lite / memcached / redis)

src / repositories (Ein Wrapper von 'Speicherimplementierungen' mit einer gewissen Speicherlogik, einer gemeinsamen Schnittstelle und einer Rückgabeergebniskonvention.)

src / services | Logik | Entitäten (App-Geschäftslogik)

src / controller (Wird in der Webentwicklung verwendet, um Serveranforderungen an Ihre Dienste weiterzuleiten.)

src / modules | systems (Modulare Systeme, die die allgemeine Funktionalität Ihres Frameworks erweitern. Services können Module verwenden, jedoch nicht umgekehrt.)

src / helpers (Helper- oder Wrapper-Klassen wie z. B. String-Manipulation. Oft kann dies bei Drittanbietern bei libs | vendor vorkommen)

src / types (benannte Enums)

öffentlich | bauen | Ausgabe (Web oder C ++)

config (Setup-Dateien. YAML wird für plattformübergreifende Konfigurationsdateien immer beliebter.)

Zwischenspeicher

protokolliert

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

Bootstrap (Startet das Framework und die App)

docs (Dokumentation im Abschriftenformat .md)

Tests (Unit-Tests)

Datenbank / Migrationen (Datenbankstruktur von Grund auf neu erstellen)

database / seeds (Füllt Ihre Datenbank mit zu testenden Dummy-Daten)

libs | Hersteller (alle Software von Drittanbietern. 'libs' unter C ++ und 'vendor' normalerweise unter PHP)

Vermögenswerte Ressourcen (Bilder / Sounds / Skripte / Json / beliebige Medien)

Heroselohim
quelle
1

Mit objektorientierten Sprachen können Sie Namespaces erstellen. Diese logische Aufteilung, mit der Teile der Anwendung getrennt werden, um eine Kopplung zu vermeiden, ist die Hauptursache für die Aufteilung des Speicherorts der logischen Dateien. Die Kopplung als Grund für das Aufteilen von Namespaces ist ein guter Ausgangspunkt für den Start von http://en.wikipedia.org/wiki/Software_package_metrics .

Andere haben darüber gesprochen, das Projekt in Bezug auf build einzurichten, aber sobald Sie sich mit der Quelle befasst haben, geht es darum, was Sinn macht - verwenden Sie einfach, wie Sie den Code trotzdem logisch aufteilen.

Travis
quelle