Vertikální slice architektura vs. Tradiční DDD
Tradiční přístup k DDD
Tradiční přístup k DDD, často označovaný jako "vrstvený" (layered), organizuje kód do vrstev podle technické odpovědnosti [1]. Typické vrstvy v tradičním DDD jsou:
- Prezentační vrstva (Presentation Layer) - Zodpovědná za interakci s uživatelem.
- Aplikační vrstva (Application Layer) - Koordinuje aplikační aktivity a deleguje práci doménové vrstvě.
- Doménová vrstva (Domain Layer) - Obsahuje doménový model a doménovou logiku.
- Infrastrukturní vrstva (Infrastructure Layer) - Poskytuje technické služby pro ostatní vrstvy.
Příklad: Tradiční struktura DDD projektu
src/
├── Presentation/ # Prezentační vrstva
│ └── Controller/
│ └── UserController.php
├── Application/ # Aplikační vrstva
│ ├── Service/
│ │ └── UserService.php
│ └── DTO/
│ └── UserDTO.php
├── Domain/ # Doménová vrstva
│ ├── Model/
│ │ └── User.php
│ ├── Repository/
│ │ └── UserRepository.php
│ └── Service/
│ └── DomainUserService.php
└── Infrastructure/ # Infrastrukturní vrstva
├── Repository/
│ └── DoctrineUserRepository.php
└── Persistence/
└── Doctrine/
└── Mapping/
└── User.orm.xml
V tradičním přístupu jsou vrstvy organizovány horizontálně, což znamená, že každá vrstva poskytuje služby vrstvě nad ní. Tento přístup je často znázorňován jako "cibulová" nebo "hexagonální" architektura [2].
Vertikální slice architektura (Vertical Slice Architecture)
Vertikální slice architektura (někdy nepřesně označovaná jako "horizontální DDD") organizuje kód podle funkcí (feature slices) místo technických vrstev [3]. Každá funkce (feature) obsahuje všechny vrstvy potřebné pro její implementaci, což umožňuje lepší modularitu a nezávislost jednotlivých částí aplikace.
Příklad: Struktura projektu s vertikální slice architekturou
src/
├── UserManagement/ # Bounded Context: Správa uživatelů
│ ├── Registration/ # Feature: Registrace uživatelů
│ │ ├── Domain/ # Doménová logika pro registraci
│ │ ├── Application/ # Aplikační logika pro registraci
│ │ │ ├── Command/
│ │ │ │ ├── RegisterUser.php
│ │ │ │ └── RegisterUserHandler.php
│ │ │ └── Service/
│ │ │ └── RegistrationService.php
│ │ └── Presentation/ # Prezentační vrstva pro registraci
│ │ ├── Controller/
│ │ │ └── UserRegistrationController.php
│ │ └── Form/
│ │ └── UserRegistrationForm.php
│ ├── Profile/ # Feature: Profil uživatele
│ │ ├── Application/ # Aplikační logika pro profil
│ │ │ ├── Query/
│ │ │ │ ├── GetUserProfile.php
│ │ │ │ └── GetUserProfileHandler.php
│ │ └── Presentation/ # Prezentační vrstva pro profil
│ │ ├── Controller/
│ │ │ └── UserProfileController.php
│ │ └── ViewModel/
│ │ └── UserProfileViewModel.php
│ ├── Domain/ # Sdílená doménová logika pro celý kontext
│ │ ├── Model/
│ │ │ └── User.php # Entita (Aggregate Root)
│ │ ├── ValueObject/
│ │ │ ├── UserId.php
│ │ │ └── Email.php
│ │ └── Repository/
│ │ └── UserRepository.php # Rozhraní
│ └── Infrastructure/ # Infrastruktura pro celý kontext
│ └── Repository/
│ └── DoctrineUserRepository.php
├── OrderManagement/ # Bounded Context: Správa objednávek
│ ├── Checkout/ # Feature: Pokladna
│ │ ├── Application/
│ │ │ ├── Command/
│ │ │ │ ├── CreateOrder.php
│ │ │ │ └── CreateOrderHandler.php
│ │ └── Presentation/
│ │ ├── Controller/
│ │ │ └── CheckoutController.php
│ │ └── Form/
│ │ └── CheckoutForm.php
│ └── ... (podobná struktura jako u UserManagement)
└── Shared/ # Sdílené komponenty pro celý systém
└── Domain/
└── Exception/
└── DomainException.php
Ve vertikální slice architektuře jsou funkce (features) organizovány jako vertikální řezy (slices) přes všechny vrstvy, přičemž každá funkce obsahuje všechny vrstvy potřebné pro její implementaci. Tento přístup minimalizuje vazby mezi jednotlivými funkcemi a maximalizuje vazby uvnitř funkce [4]. Zároveň zachovává principy DDD tím, že respektuje bounded contexts a doménový model.
Porovnání přístupů
Aspekt | Tradiční (vertikální) DDD | Vertikální slice architektura |
---|---|---|
Organizace kódu | Podle technických vrstev | Podle funkcí (features) |
Vazby | Silné vazby mezi vrstvami | Silné vazby uvnitř funkce, slabé vazby mezi funkcemi |
Změny | Změna často vyžaduje úpravy ve více vrstvách | Změna je obvykle omezena na jednu funkci |
Testovatelnost | Často vyžaduje mnoho mocků pro testování | Snazší testování, méně mocků |
Škálovatelnost | Může být obtížné škálovat při růstu aplikace | Snazší škálování, funkce mohou být rozděleny do mikroslužeb |
Složitost | Jednodušší pro pochopení na začátku | Může být složitější pro pochopení na začátku |
Vhodnost pro CQRS | Vyžaduje dodatečnou práci pro implementaci CQRS | Přirozeně podporuje CQRS [5] |
Kdy použít který přístup
Kdy použít tradiční DDD:
- Když je tým zvyklý na tradiční architekturu.
- Pro menší aplikace s jasně definovanými vrstvami.
- Když je důležitá jasná separace technických vrstev.
- Pro aplikace s jednodušší doménovou logikou.
Kdy použít vertikální slice architekturu:
- Pro větší a složitější aplikace [6].
- Když je důležitá modularita a nezávislost funkcí.
- Pro aplikace, které budou v budoucnu rozděleny do mikroslužeb.
- Když chcete implementovat CQRS.
- Pro týmy, které jsou zvyklé na agilní vývoj a časté změny.
Implementace v Symfony 7
Symfony 7 poskytuje mnoho nástrojů a komponent, které usnadňují implementaci obou přístupů k DDD [7].
Implementace tradičního DDD v Symfony 7:
Pro implementaci tradičního DDD v Symfony 7 můžete použít standardní adresářovou strukturu Symfony a rozdělit kód do vrstev:
src/
├── UserManagement/ # Bounded Context: Správa uživatelů
│ ├── Presentation/ # Prezentační vrstva
│ │ ├── Controller/
│ │ │ ├── UserController.php
│ │ │ └── RegistrationController.php
│ │ └── ViewModel/
│ │ └── UserViewModel.php
│ ├── Application/ # Aplikační vrstva
│ │ ├── Command/
│ │ │ ├── RegisterUser.php
│ │ │ └── RegisterUserHandler.php
│ │ ├── Query/
│ │ │ ├── GetUser.php
│ │ │ └── GetUserHandler.php
│ │ └── Service/
│ │ └── UserApplicationService.php
│ ├── Domain/ # Doménová vrstva
│ │ ├── Model/
│ │ │ └── User.php # Entita (Aggregate Root)
│ │ ├── ValueObject/
│ │ │ ├── UserId.php
│ │ │ └── Email.php
│ │ ├── Event/
│ │ │ └── UserRegistered.php
│ │ ├── Repository/
│ │ │ └── UserRepository.php # Rozhraní
│ │ └── Service/
│ │ └── UserDomainService.php
│ └── Infrastructure/ # Infrastrukturní vrstva
│ ├── Repository/
│ │ └── DoctrineUserRepository.php
│ └── Persistence/
│ └── Doctrine/
│ └── Mapping/
│ └── User.orm.xml
├── OrderManagement/ # Bounded Context: Správa objednávek
│ ├── Presentation/ # Prezentační vrstva
│ ├── Application/ # Aplikační vrstva
│ ├── Domain/ # Doménová vrstva
│ └── Infrastructure/ # Infrastrukturní vrstva
└── Shared/ # Sdílené komponenty
└── Domain/ # Sdílená doménová logika
└── Exception/
└── DomainException.php
Implementace vertikální slice architektury v Symfony 7:
Pro implementaci vertikální slice architektury v Symfony 7 můžete organizovat kód podle funkcí (features) [8]:
src/
├── UserManagement/ # Bounded Context: Správa uživatelů
│ ├── Registration/ # Feature: Registrace uživatelů
│ │ ├── Domain/ # Doménová logika pro registraci
│ │ │ ├── Event/
│ │ │ │ └── UserRegistered.php
│ │ │ └── Service/
│ │ │ └── RegistrationDomainService.php
│ │ ├── Application/ # Aplikační logika pro registraci
│ │ │ ├── Command/
│ │ │ │ ├── RegisterUser.php
│ │ │ │ └── RegisterUserHandler.php
│ │ │ └── Service/
│ │ │ └── RegistrationService.php
│ │ └── Presentation/ # Prezentační vrstva pro registraci
│ │ ├── Controller/
│ │ │ └── UserRegistrationController.php
│ │ └── Form/
│ │ └── UserRegistrationForm.php
│ ├── Profile/ # Feature: Profil uživatele
│ │ ├── Application/ # Aplikační logika pro profil
│ │ │ ├── Query/
│ │ │ │ ├── GetUserProfile.php
│ │ │ │ └── GetUserProfileHandler.php
│ │ │ └── Service/
│ │ │ └── ProfileService.php
│ │ └── Presentation/ # Prezentační vrstva pro profil
│ │ ├── Controller/
│ │ │ └── UserProfileController.php
│ │ └── ViewModel/
│ │ └── UserProfileViewModel.php
│ ├── Domain/ # Sdílená doménová logika pro celý kontext
│ │ ├── Model/
│ │ │ └── User.php # Entita (Aggregate Root)
│ │ ├── ValueObject/
│ │ │ ├── UserId.php
│ │ │ └── Email.php
│ │ └── Repository/
│ │ └── UserRepository.php # Rozhraní
│ └── Infrastructure/ # Infrastruktura pro celý kontext
│ └── Repository/
│ └── DoctrineUserRepository.php
├── OrderManagement/ # Bounded Context: Správa objednávek
│ ├── Checkout/ # Feature: Pokladna
│ │ ├── Domain/
│ │ ├── Application/
│ │ └── Presentation/
│ └── ... (podobná struktura jako u UserManagement)
└── Shared/ # Sdílené komponenty pro celý systém
└── Domain/
└── Exception/
└── DomainException.php
Symfony 7 poskytuje mnoho komponent, které jsou užitečné pro implementaci vertikální slice architektury [9]:
- Messenger komponenta - Pro implementaci CQRS a asynchronní zpracování [10].
- Validator komponenta - Pro validaci doménových objektů.
- Form komponenta - Pro zpracování vstupů od uživatele.
- Security komponenta - Pro autentizaci a autorizaci.
- Doctrine ORM - Pro persistenci doménových objektů.
Důležité poznámky
Při implementaci vertikální slice architektury v Symfony 7 je důležité:
- Minimalizovat vazby mezi jednotlivými funkcemi (features).
- Používat CQRS pro oddělení čtení a zápisu [11].
- Používat doménové události pro komunikaci mezi funkcemi.
- Definovat jasné hranice mezi funkcemi.
V další kapitole se podíváme na základní koncepty DDD a jak je implementovat v Symfony 7.