Добавлено описание структуры Signed-off-by: Андрей Брусницын <brusnitsyn@brusoff.su>
8.8 KiB
8.8 KiB
Схема 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);
}
}