Привожу тут слегка причёсанную цитату @fesor (оригинал):
Модуль — это единица кода. Например, файл, директория, пакет, класс или неймспейс. Модули "хорошие", когда между ними низкая связанность (low coupling) и внутри высокое зацепление (high cohesion). С ростом проекта растет необходимость изоляции этих модулей. Простой риск менеджмент — ты не можешь случайно сломать фичу, если ты её не трогал. Единственный верный вариант в этом плане — рассматривать фичи как модули и искать у них границы, выделять точки расширения, чтобы минимизировать необходимость их "менять", следить за пересечениями границ.
Если проект на 2-3 разработчика, то любая структура будет работать. Если проект на 20-30 разработчиков — ситуация будет чуть иная. И проблемы это все нетехнические — машинам похеру на структуру кода. Это в основном проблемы коммуникации между людьми и задача управления сложностью. Любой успешный продукт довольно быстро начинает расти в плане количества людей, и проблемы коммуникации увеличиваются как факториал количества участников. Во всяком случае, если не изолировать фичи.
При разделении проекта на фичи ты будешь ошибаться и не один раз. Тем более на начальных этапах, когда не очень понятно, что проект из себя представляет и как оно должно быть. Главное, что если не пытаться и не пробовать, то ты быстро придешь к крайне неэффективному процессу разработки.
Данный скелетон демонстрирует, как можно организовать модульность в проекте на базе компонента Symfony Dependency Injection.
Здесь модуль — это неймспейс с классами и конфигами DI и роутинга. Когда модули всё своё "носят" с собой, их легко переименовывать, перегруппировывать, анализировать и удалять. Особенно удобно в этом случае использовать конфигурацию в формате PHP, тогда рефакторинг в IDE становится полностью автоматическим.
Изменения относительно стандартного symfony/skeleton
- Удалён
config/services.yaml
. Он не нужен, так как вендорные бандлы конфигурируются вconfig/packages
, а модули проекта конфигурируются в своихdi.php
. - В
src/Kernel.php
прописан импортdi.php
иrouting.php
из любых поддиректорийsrc
. - В случае использования
Doctrine ORM
автоматически импортируется маппинг для каждого модуля по соответствующему внутреннему путиInfrastructure/Doctrine/Mapping
в форматеxml
. - Добавлен модуль
src/MyBusinessFeature
. Обратите внимание, что вdi.php
тоже прописан неймспейс модуля — благодаря этому PhpStorm будет переносить его вслед за классами при рефакторинге.
Бандл — это, безусловно, модуль. Однако, он не подходит для описанных выше задач.
- Модуль в
src
— это бизнесовый или инфраструктурный код, бандл — только инфраструктурный. Как правило, бандл — это бридж между какой-нибудь библиотекой и Symfony Http Kernel. Бандлы решают технические задачи и не имеют отношения к предметной области конкретного проекта. - Модуль в
src
стремится быть конкретным в соответствии с требованиями проекта и моделью предметной области. Бандл стремится быть универсальным и конфигурируемым. - Модуль в
src
— это способ декомпозиции кода проекта. Бандл — это расширение функционала Symfony Framework, поставляемое в форме пакета для Composer. - Модуль в
src
требует только наличия файлаdi.php
. Бандл — более сложный модуль: он требует реализации классовBundle
иExtension
.