Как мне организовать свое исходное дерево?


89

Я - индивидуальный разработчик, работающий, в основном, над веб-проектами (W / LAMP) и, иногда, над проектами C / C ++ (не-GUI) среднего масштаба.

Я часто борюсь с структурированием своего дерева исходного кода. На самом деле, обычно я не завершаю проект, не выгружая все дерево и не переставляя фрагменты три-четыре раза, что действительно требует больших усилий, и, кроме того, конечный результат кажется компромиссом.

Иногда я сталкиваюсь с чрезмерной классификацией источника - очень длинным деревом папок и подпапок. В других случаях я просто в конечном итоге концентрирую все файлы в определенной папке, исходя из более широкой цели, которой они служат, и, таким образом, приводя к «хаотическим» папкам в источнике.

Я хотел бы спросить:

  • Существуют ли какие-либо принципы / логика / лучшие практики, которые могут помочь мне лучше структурировать дерево исходных текстов?
  • Существуют ли какие-либо графические / диаграммные методы (например, DFD в случае потока данных), которые могут помочь мне заранее визуализировать дерево исходных текстов на основе анализа проекта?
  • Какую стратегию принять для структурирования мультимедийного файлового дерева, связанного с проектом?

О вознаграждении : я ценю существующие ответы, когда участники делятся своими практиками, однако я хотел бы побудить более общие и поучительные ответы (или ресурсы) и больше ответов от участников.


8
Сейчас у меня нет времени на сочинение, но «назовите вещи такими, какие они есть», «положите вещи на свои места», «держите похожие вещи рядом» и, наконец, «не беспокойтесь об этом» надеюсь, у вас есть IDE, которая поможет вам быстро перемещаться между фрагментами кода ".
Джон Сондерс

@ Джон, я не очень хорош в IDE, я обычно вытаскиваю Notepad ++ или vi в зависимости от ОС. Это делает вещи немного сложнее. Остальные пункты полезны, но, опять же, все сводится к принятию хитрых решений, таких как функции журнала (журналы ошибок и т. Д.), Более близкие к логике приложения или DAL или управлению кэшем или менеджерам представлений. Ошибки имеют почти равную вероятность появления на любом из них.
check123

3
Может быть, как только вы дойдете до такой точки, у вас будет время поработать с некоторыми инструментами. И ведение журнала явно является межфункциональной задачей, используемой всеми частями приложения (если вы используете код, требующий ведения журнала). Еще одно маленькое высказывание: «поместите код над кодом, который его использует», поэтому ведение журнала должно быть в самом верху, возможно, в \ utilities.
Джон Сондерс

@Джон: очень ценится. Может быть, я должен начать искать IDE. Затмение кажется многообещающим.
check123

1
@ check123 «... три-четыре раза переставляя кусочки ...» Обычная практика: «Поэтому вопрос управления заключается не в том, стоит ли создавать пилотную систему и выбрасывать ее. Ты сделаешь это. Единственный вопрос заключается в том, стоит ли планировать заранее создать одноразовый проект или пообещать предоставить одноразовый заказ клиентам ». - Фредерик П. Брукс-младший,« Мифический человеко-месяц: очерки по программной инженерии »
shawnhcorey,

Ответы:


25

Структура дерева исходных текстов должна отражать архитектуру; Как следствие, хорошо структурированная архитектура может привести к хорошо структурированной структуре исходного дерева. Я предлагаю прочитать шаблон POSA1 Layers , попытаться вписать вашу архитектуру в многоуровневую структуру, затем назвать каждый из полученных слоев и использовать его в качестве основы для исходной иерархии. Взяв за основу общую трехуровневую архитектуру :

  • presentation / webService (представить интерфейс веб-сервиса для нашей бизнес-логики)
  • logic / * (модули бизнес-логики здесь)
  • storage / sql (здесь API-интерфейсы внутреннего хранилища - для хранения в базе данных используется интерфейс SQL)
  • util / * (код утилиты - используется всеми другими уровнями, но это не относится к внешнему утилиту, здесь)

Обратите внимание, что слои не содержат код напрямую, а строго используются для организации модулей.

В модуле я использую следующий вид макета:

  • <module> (путь к модулю напрямую; определяет модульный интерфейс)
  • <module>/impl/<implName> (конкретная реализация модульного интерфейса)
  • <module>/doc (Документация по использованию модуля)
  • <module>/tb (код юнит-теста для модуля)

где <module>находится в хранилище в соответствии со слоем, к которому он принадлежит.


5
+1: Схема дерева исходных текстов должна отражать архитектуру - очевидная вещь, которую я пропустил.
check123

Как вы управляете безопасными файлами - файлами, доступ к которым разрешен только авторизованным пользователям?
check123

@ check123 Я не уверен, что понимаю вопрос. Я сосредоточился на организации исходных модулей, а не на поддержке файлов для проекта, а исходный код обычно должен быть доступен каждому. (Существуют исключения, и я использую каталог dist / выше всего кода с нестандартными ограничениями на использование / изменение.)
Эйдан Калли

48

Я не могу дать вам много советов, связанных с веб-проектами, но вот как я структурирую свое дерево в программном проекте (в основном с точки зрения C / C ++):

  • /
    • src - Исходные файлы, написанные мной
    • ext - содержит сторонние библиотеки
      • Имя_библиотеки-1.2.8
        • include - Заголовки
        • lib - скомпилированные файлы lib
        • Donwload.txt - содержит ссылку для загрузки используемой версии
    • ide - я храню файлы проекта здесь
      • vc10 - я размещаю файлы проекта в зависимости от IDE
    • bin - скомпилированный exe идет сюда
    • build - файлы сборки компилятора
    • doc - любая документация
    • ПРОЧТИ МЕНЯ
    • УСТАНОВИТЬ
    • КОПИРОВАНИЕ

Несколько заметок:

  1. Если я пишу библиотеку (и я использую C / C ++), я собираюсь организовать свои исходные файлы сначала в две папки, называемые «include» и «src», а затем по модулям. Если это приложение, то я собираюсь организовать их просто по модулю (заголовки и источники будут находиться в одной папке).

  2. Файлы и каталоги, которые я перечислил выше курсивом, я не буду добавлять в репозиторий кода.


В чем разница между ide и build ?
М. Дадли

3
ideИменно там я храню файлы проекта сами. buildсодержит объектные файлы, сгенерированные компилятором. Различные IDE могут использовать один и тот же компилятор, поэтому я храню файлы проекта IDE отдельно от объектных файлов, созданных компилятором.
Пол

так что build == obj (термин, используемый во многих других системах)
gbjbaanb

@gbjbaanb Да, наверное. Это не имеет большого значения, так как этот каталог не помещается в хранилище. :) Я назвал это «сборкой», потому что это то, что называется в IDE, которую я использовал att (Visual Studio).
Пол

Что делать, если вашему exe нужен какой-нибудь dll для запуска? Вы копируете все файлы dll в тот же каталог, что и exe? Используете ли вы какие-либо события после сборки?
Вакан Танка

14

Хотя Maven Standard Directory Layout специфичен для Java, но он может послужить хорошей основой и для других типов проектов.

Вот основная структура (вы можете заменить каталоги java на php, cpp и т. Д.):

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

Структура в основном разбивается на 'src / main' и 'src / test', а затем группируется по типу.


5

Я действительно не знаю о соглашениях, но все мои основные проекты выполняются с использованием Symfony Framework, и я привык к древовидной структуре, как показано ниже:

корень /

  • Программы
  • Имя приложения
    • config (файлы конфигурации приложения)
    • lib (php файлы приложения)
    • модули (модульное распределение функциональности)
      • module_name
        • шаблоны (html)
        • действия (код php)
  • конфинг (файлы конфигурации проекта)
  • lib (код php, который можно использовать в проекте отверстия)
  • модель (классы, которые представляют информацию о проекте)
    • база
  • form (php файлы, которые обрабатывают формы, это может быть довольно трудно достичь без Symfony)
    • базовый (базовые классы формы)
  • Web
  • CSS
    • картинки
    • file.css
  • JS
  • log (файлы журнала, которые могут быть сгенерированы)
  • данные (информация, относящаяся к данным, например, SQL-патчи или что-то еще)
  • SQL
  • плагины (используемые библиотеки, которые могут быть объединены с любым приложением проекта)

Если вы заинтересованы, пожалуйста, прочитайте документацию Symfony по этому вопросу для дальнейших запросов ( MVC и Code Organization on Symfony ).


Ваша папка CSS централизована? Я имею в виду, что все ваши CSS (по всему проекту) находятся в одном каталоге?
check123

Необязательно, вы могли бы разделить его, но так как большинство моих проектов, как правило, имеют только 2 приложения (внешний и внутренний), CSS-файлов не так много (плагины всегда имеют свою собственную веб-папку для абстракции)
guiman

5

В идеале организация имеет единый репозиторий, структура которого предназначена для увеличения взаимодействия между инжинирингом и бизнесом и содействия повторному использованию.

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

продукты

Одна папка для каждого продукта; помогает понять, как программное обеспечение поддерживает бизнес.

В идеале каждый «продукт» - это не более, чем файл конфигурации, указывающий, какие системы нужно вызывать и как они должны быть настроены. Подпапка doc может содержать краткое описание \ spec & любой рекламный материал и т. Д.

Разделяя продукты и системы, мы передаем потенциальные возможности повторного использования клиентской стороне бизнеса и разбиваем бункеры для каждого продукта. (Это контрастирует с подходом «продуктовой линейки» к той же проблеме)

системы

Одна папка на систему; помогает донести основные возможности и возможности / ценность содержимого хранилища.

  1. Файлы «Управление конфигурацией», определяющие среды сборки и развертывания.
  2. Конфигурация тестирования на уровне системы (может быть значительным количеством).
  3. Логика и функциональность высшего уровня; наиболее тяжелая работа выполняется библиотечными функциями.

библиотека

Многоразовые компоненты, используемые различными системами. Большая часть деятельности по разработке организована вокруг производства библиотек, а не систем, поэтому повторное использование «внедряется» в процесс разработки.

DevOps

Построение, непрерывная интеграция и другие функции автоматизации разработки.

Заключение

Дерево исходных текстов является ключевым элементом документации и определяет подход, структуру и психологию отношений бизнеса с его запатентованной технологией.

Драйверы для этого подхода описаны более подробно в моем ответе на этот вопрос: https://softwareengineering.stackexchange.com/questions/43733/who-organizes-your-matlab-code/59637#59637


Примечание. Может быть полезно назвать папки так, чтобы они были совместимы с иерархиями продуктов, описанными в справочнике по проектированию систем INCOSE.
Уильям Пейн

3

То, что я пытаюсь сделать для каждого проекта, выглядит примерно так:

  • src - исходные файлы, папка для каждого пространства имен / пакета для простого извлечения файлов (даже заголовочных файлов для C / C ++)
  • ext - для внешних / сторонних библиотек просто добавить внешние (такие как SVN-репозитории). Внутри папка для каждой библиотеки (бинарные и включаемые файлы)
  • bin - для встроенных двоичных файлов, может быть быстро экспортирован для выпуска
    • inc - для файла заголовков C / C ++ (копируется в IDE / makefile / etc ...)
  • out - для всех временно сгенерированных файлов (.class, .obj и т. д.), и их можно игнорировать (например, SVN)
  • doc - для любой документации, обычно генерируемой с помощью Doxygen
  • res - разместив ресурсы здесь, можно разделить исходные текстовые файлы и двоичные ресурсы, используемые программой. У меня действительно нет определенной иерархии внутри.
    • config - для некоторых файлов конфигурации
    • Drawable - для некоторых картинок или иконок

Все файлы IDE или make-файлы сохраняются непосредственно в корневом каталоге, если вы используете только один из них.


2

Я делаю что-то вроде этого. Хорошо работает для кроссплатформенной игры, которую я делаю в свободное время. К сожалению, в работе все гораздо менее организовано ...

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

2

Для моих команд мы стараемся внедрить стандартную структуру в проектах, чтобы было легко найти вещи, так как команда меняет контекст и избегает повторного изучения каждый раз. Не всем проектам нужны все системы, поэтому мы начинаем с минимального набора.

/ Источник / Компонент / Язык

/ Источник / Компонент / Третья сторона /

/ Документация / Требования

/ Документация / Дизайн

/ Тесты / Automated / Unit

/ Тесты / Автоматизированная / ToolName

/ Тесты / Руководство

Это приводит к некоторому дублированию, особенно в стороннем коде и библиотеках, но по крайней мере мы никогда не забываем ответ на что-то вроде «Что использует редактор RogueWave?»


1
Компоненты с заглавными буквами для меня выглядят глупо и бессмысленно. Почему много строчных? Это гораздо проще для людей (хотя инструментам все равно, включая файловые менеджеры WIMP ), и одинаково хорошо читает благодаря разделителям путей. Окончательная победа для меня.
ulidtko

2

Мне нравятся идеи, представленные на этой странице www.javapractices.com/topic/TopicAction.do?Id=205 . По сути, рекомендация состоит в том, чтобы организовать ваш проект в функции (или модули, компоненты). В дополнение к причинам, представленным там:

  1. Меньшая когнитивная нагрузка, когда вы задумываетесь над областью кода, над которым вы работаете, поскольку у вас есть гарантия того, что любой код в функции, над которой вы работаете, является "приватным".
  2. Существует дополнительное чувство безопасности, когда вы гарантируете, что изменяете код только для данной функции. Например, вы не нарушите ничего, кроме функции, над которой вы работаете. Опять же, это из-за "частной функции".
  3. Меньшая когнитивная загрузка проста, потому что меньше файлов, которые вы можете увидеть для данного пакета. Я уверен, что все видели пакет, содержащий более 15 файлов.

Обратите внимание, что это сфокусировано на пакетах Java (пространства имен). Для больших проектов я рекомендую по тем же причинам разделить проект на несколько проектов (как в нескольких проектах maven), представляющих бизнес-функцию. Для Maven проектов, я рекомендую это чтение .

Пока что проекты, в которых я принимал участие, не соответствуют этим. Есть много причин, но вот несколько:

  1. Неправильное понимание модификатора доступа по умолчанию в Java (большинство неправильно понятого модификатора доступа согласно этой книге )
  2. «Argumentum ad populum»: преобладающая культура «пакет за слоем» (вероятно, вызванная Причиной № 1)

Я думаю, что есть упущенная возможность предотвратить сложность, если исходная организация проекта не будет воспринята всерьез в начале проекта, как сказал архитектор Александр:

«Как скажет любой дизайнер, это первые шаги в процессе проектирования, которые имеют наибольшее значение. Первые несколько штрихов, которые создают форму, несут в себе судьбу остальных». - Кристофер Александр

В зависимости от размера и сложности проекта упущенная возможность сократить расходы или окупаемость инвестиций может быть очень большой. (Мне интересно посмотреть исследование, чтобы увидеть точные цифры для этого)


2

Я рекомендую скачать различные фреймворки или движки и посмотреть, как огромные команды разработчиков обрабатывают макет своих папок.

Существует так много способов упорядочить файлы, что лучше выбрать один и попытаться придерживаться его в любом конкретном проекте. Придерживайтесь определенного соглашения до завершения или модернизации, чтобы избежать ошибок и потери ненужного времени.

Вы можете загрузить платформы Laravel, Symphony или Codeigniter для веб-проектов, чтобы иметь мгновенный макет папки, который работает.

Поэтому я постараюсь передать макет папок, общий для любой разработки:

MVC (Model View Controller) дает хорошую парадигму организации.

Корневым исходным кодом может быть src (C ++) или приложение (веб-разработка)

Файловая структура, которая не имеет четкой цели для классов, которые она группирует, определенно вызовет путаницу. Это не только организация кода, но и поддержка автозагрузчиков, фабрики классов, переноса локального хранилища, удаленного хранилища и пространства имен.

Эта структура папок получена и упрощена из Laravel Framework . В этом посте я предпочитаю именовать во множественном числе, но в своих проектах я использую отдельные слова.


src / storage (реализации моделей / file-storage / api / mysql / sql-lite / memcached / redis)

src / repositories (Оболочка «реализаций хранилища» с некоторой логикой хранения, общим интерфейсом и соглашением о возвращаемых результатах.)

центр / услуги | логика | лица (App логика бизнеса)

src / controllers (используется при веб-разработке для маршрутизации запросов сервера к вашим сервисам)

SRC / модули | системы (Модульные системы, расширяющие общие функциональные возможности вашей платформы. Сервисы могут использовать модули, но не наоборот)

src / helpers (вспомогательные классы или классы-оболочки, например, манипуляции со строками. Много раз это может быть на libs | vendor при использовании третьей стороны)

src / types (Именованные перечисления)

публичный | построить | вывод (web или c ++)

config (файлы установки. YAML становится популярным для кросс-платформенных файлов конфигурации)

кэш

бревна

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

начальная загрузка (запускает фреймворк и приложение)

документы (документация написана в формате уценки .md)

тесты (юнит тестирование)

база данных / миграции (создание структуры базы данных с нуля)

база данных / семена (заполняет вашу базу фиктивными данными для проверки)

libs | vendor (все сторонние программы. 'libs' на C ++ и 'vendor' обычно на php)

активы | ресурсы (изображения / звуки / сценарии / JSON / любые медиа)


1

С объектно-ориентированными языками у вас есть возможность создавать пространства имен. Эта логическая разбивка, используемая для разделения частей приложения во избежание связывания, является основным источником разбивки расположения логических файлов. Использование связывания в качестве причины для разделения пространств имен - хорошее место для начала http://en.wikipedia.org/wiki/Software_package_metrics .

Другие говорили о настройке проекта в отношении сборки, но как только вы попадаете в сам исходный код, речь идет о том, что имеет смысл - просто в любом случае используйте то, как вы логически разбиваете код.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.