Стандартна структура (app/Models, app/Http/Controllers) групує код за типом. На сотнях класів зміна однієї фічі зачіпає десять тек, а залежності між частинами не видно.
Групування за предметною областю (модулі):
app/
Billing/ Models, Actions, Events, Policies, BillingServiceProvider
Catalog/
Shipping/
Shared/ спільне: value objects, базові класи
Laravel не нав'язує структуру - простори імен PSR-4 і провайдери дозволяють так робити без пакетів.
Що робить модулі справжніми, а не лише теками:
- Публічна поверхня. Інші модулі звертаються до
Billingчерез його дії чи сервіси, а не до таблиць і моделей напряму. - Події між модулями.
OrderPlacedзCatalogслухаєBilling- відправник не знає про отримувача. - Свої провайдери реєструють маршрути, політики, слухачі модуля.
- Перевірка меж архітектурними тестами:
arch()->expect('App\Billing')->not->toUse('App\Shipping\Models').
Чого уникати:
- переносити структуру DDD повністю на CRUD-застосунок - шари без логіки лише додають файлів;
- спільних «God»-моделей (
Userз методами всіх модулів) - кожен модуль може мати свій погляд на користувача; - ділити на мікросервіси замість модулів: межі спершу перевіряють усередині моноліту, де помилку дешево виправити.