Files
laravel-domain-template/readme.md
Андрей Брусницын 31e322d992 Добавить readme.md
Добавлено описание структуры

Signed-off-by: Андрей Брусницын <brusnitsyn@brusoff.su>
2025-11-07 10:35:52 +09:00

259 lines
8.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Схема Domain Architecture
```
app/
├── Domains/ # 🎯 ЯДРО - Бизнес-логика
│ ├── User/ # Домен Пользователи
│ │ ├── Actions/ # Бизнес-действия (Use Cases)
│ │ │ ├── CreateUserAction.php
│ │ │ ├── UpdateUserProfileAction.php
│ │ │ └── DeleteUserAction.php
│ │ ├── Models/ # Сущности предметной области
│ │ │ ├── User.php
│ │ │ └── ValueObjects/
│ │ │ └── Email.php
│ │ ├── DataTransferObjects/ # DTO - передача данных
│ │ │ ├── UserData.php
│ │ │ └── CreateUserData.php
│ │ ├── Collections/ # Кастомные коллекции
│ │ │ └── UserCollection.php
│ │ ├── Contracts/ # Интерфейсы (Абстракции)
│ │ │ ├── UserRepositoryInterface.php
│ │ │ └── PasswordHasherInterface.php
│ │ ├── Events/ # События домена
│ │ │ ├── UserCreated.php
│ │ │ └── UserUpdated.php
│ │ ├── Listeners/ # Обработчики событий
│ │ │ ├── SendWelcomeEmail.php
│ │ │ └── LogUserActivity.php
│ │ ├── Rules/ # Бизнес-правила валидации
│ │ │ └── UniqueUserEmail.php
│ │ ├── Services/ # Доменные сервисы
│ │ │ └── UserRegistrationService.php
│ │ ├── Exceptions/ # Доменные исключения
│ │ │ └── UserNotFoundException.php
│ │ └── Enums/ # Перечисления
│ │ └── UserStatus.php
│ ├── Product/ # Домен Продукты
│ │ ├── Actions/
│ │ ├── Models/
│ │ └── Contracts/
│ └── Order/ # Домен Заказы
│ ├── Actions/
│ ├── Models/
│ └── Events/
├── Application/ # 🚀 СЛОЙ ПРИЛОЖЕНИЯ
│ ├── Providers/ # Сервис-провайдеры
│ │ ├── DomainServiceProvider.php
│ │ └── AuthServiceProvider.php
│ ├── Console/ # Artisan команды
│ │ └── Commands/
│ │ └── ProcessOrdersCommand.php
│ ├── Http/ # Тонкие контроллеры
│ │ └── Requests/
│ │ └── CreateUserRequest.php
│ └── Resources/ # API Resources
│ └── UserResource.php
└── Infrastructure/ # 🔧 ИНФРАСТРУКТУРА
├── Http/ # Внешние адаптеры
│ ├── Controllers/
│ │ ├── UserController.php
│ │ └── Api/
│ │ └── V1/
│ └── Middleware/
├── Database/ # Данные и персистентность
│ ├── Migrations/
│ ├── Seeders/
│ ├── Factories/
│ └── Repositories/ # Реализации репозиториев
│ ├── Eloquent/
│ │ └── UserRepository.php
│ └── CachedUserRepository.php
├── Notifications/ # Внешние уведомления
│ └── UserWelcomeNotification.php
├── Mail/ # Email шаблоны
│ └── WelcomeEmail.php
└── Services/ # Внешние сервисы
├── Payment/
│ └── StripePaymentService.php
└── Sms/
└── TwilioSmsService.php
```
## 🔄 Поток данных через слои
```
HTTP Request
→ Infrastructure/Http/Controllers/UserController
→ Application/Http/Requests/CreateUserRequest (валидация)
→ Domains/User/Actions/CreateUserAction (бизнес-логика)
→ Domains/User/Contracts/UserRepositoryInterface
→ Infrastructure/Database/Repositories/UserRepository (реализация)
→ Database
```
## 📋 Детальное описание компонентов
**🎯 Domains/ - Ядро бизнес-логики**
**Actions/** - Бизнес-действия (Use Cases):
```php
namespace App\Domains\User\Actions;
class CreateUserAction
{
public function __construct(
private UserRepositoryInterface $users,
private PasswordHasherInterface $hasher
) {}
public function execute(CreateUserData $data): User
{
// Вся бизнес-логика создания пользователя
$user = new User([
'name' => $data->name,
'email' => $data->email,
'password' => $this->hasher->hash($data->password),
]);
$this->users->save($user);
event(new UserCreated($user));
return $user;
}
}
```
**Models/** - Сущности с бизнес-логикой:
```php
namespace App\Domains\User\Models;
class User extends Model
{
public function activate(): void
{
$this->status = UserStatus::ACTIVE;
$this->activated_at = now();
}
public function isActive(): bool
{
return $this->status === UserStatus::ACTIVE;
}
}
```
**Contracts/** - Абстракции (Dependency Inversion):
```php
namespace App\Domains\User\Contracts;
interface UserRepositoryInterface
{
public function findByEmail(string $email): ?User;
public function save(User $user): void;
public function delete(User $user): void;
}
```
**DataTransferObjects/** - Объекты передачи данных:
```php
namespace App\Domains\User\DataTransferObjects;
class CreateUserData extends DataTransferObject
{
public string $name;
public string $email;
public string $password;
public static function fromRequest(CreateUserRequest $request): self
{
return new self([
'name' => $request->validated('name'),
'email' => $request->validated('email'),
'password' => $request->validated('password'),
]);
}
}
```
## 🚀 Application/ - Слой приложения
**Тонкие контроллеры**:
```php
namespace App\Infrastructure\Http\Controllers;
use App\Domains\User\Actions\CreateUserAction;
use App\Domains\User\DataTransferObjects\CreateUserData;
class UserController extends Controller
{
public function store(CreateUserRequest $request, CreateUserAction $createUser)
{
$userData = CreateUserData::fromRequest($request);
$user = $createUser->execute($userData);
return new UserResource($user);
}
}
```
## 🔧 Infrastructure/ - Техническая реализация
**Реализации репозиториев**:
```php
namespace App\Infrastructure\Database\Repositories\Eloquent;
use App\Domains\User\Contracts\UserRepositoryInterface;
use App\Domains\User\Models\User;
class UserRepository implements UserRepositoryInterface
{
public function findByEmail(string $email): ?User
{
return User::where('email', $email)->first();
}
public function save(User $user): void
{
$user->save();
}
}
```
## 🔗 Взаимодействие между слоями
**Dependency Rule**:
- **Domains** ← ничего не зависит от других слоев
- **Application** ← зависит только от Domains
- **Infrastructure** ← зависит от Domains и Application
**Пример регистрации зависимостей**:
```php
// app/Application/Providers/DomainServiceProvider.php
namespace App\Application\Providers;
use Illuminate\Support\ServiceProvider;
use App\Domains\User\Contracts\UserRepositoryInterface;
use App\Infrastructure\Database\Repositories\Eloquent\UserRepository;
class DomainServiceProvider extends ServiceProvider
{
public function register(): void
{
// Связывание интерфейсов с реализациями
$this->app->bind(UserRepositoryInterface::class, UserRepository::class);
$this->app->bind(PasswordHasherInterface::class, BcryptPasswordHasher::class);
// Регистрация Actions
$this->app->singleton(\App\Domains\User\Actions\CreateUserAction::class);
}
}
```