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

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

8.8 KiB
Raw Blame History

Схема 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):

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/ - Сущности с бизнес-логикой:

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):

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/ - Объекты передачи данных:

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/ - Слой приложения

Тонкие контроллеры:

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/ - Техническая реализация

Реализации репозиториев:

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

Пример регистрации зависимостей:

// 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);
    }
}