Чистая архитектура в PHP: пошаговое руководство.

Чистая архитектура (Clean Architecture), предложенная Робертом Мартином (дядя Боб), представляет собой подход к проектированию программного обеспечения, при котором бизнес-логика отделена от технических деталей: базы данных, фреймворков, пользовательского интерфейса и прочего окружения. Такой подход повышает устойчивость, тестируемость и сопровождаемость приложений. В данной статье будет рассмотрено, как реализовать принципы чистой архитектуры на языке PHP.
Основные принципы Clean Architecture
Чистая архитектура опирается на следующие принципы:
- Разделение ответственности — каждый слой отвечает за свою часть логики.
- Зависимости направлены внутрь — внешние слои зависят от внутренних, но не наоборот.
- Независимость от фреймворков — бизнес-логика не зависит от Laravel, Symfony и других.
- Тестируемость — каждый компонент может быть протестирован изолированно.
- Изоляция от внешних систем — база данных, API, UI — всё это инфраструктура, а не ядро.
Слои архитектуры
Слой | Описание |
---|---|
Frameworks | Фреймворки, HTTP-контроллеры, UI |
Interface Adapters | DTO, контроллеры, репозитории |
Application Core | Use Cases, сервисы приложения |
Domain Core | Сущности, бизнес-логика |
Пошаговое руководство по реализации
Шаг 1: Инициализация проекта
composer init
composer require --dev phpunit/phpunit
Шаг 2: Структура каталогов
src/
├── Domain/
│ ├── Entity/
│ ├── Repository/
│ └── ValueObject/
├── Application/
│ ├── UseCase/
│ └── Service/
├── Infrastructure/
│ ├── Persistence/
│ ├── Controllers/
│ └── Framework/
└── Shared/
└── Kernel/
Шаг 3: Пример сущности (Domain Layer)
// src/Domain/Entity/User.php
namespace App\Domain\Entity;
class User {
private string $id;
private string $email;
public function __construct(string $id, string $email) {
$this->id = $id;
$this->email = $email;
}
public function getEmail(): string {
return $this->email;
}
}
Шаг 4: Интерфейс репозитория
// src/Domain/Repository/UserRepositoryInterface.php
namespace App\Domain\Repository;
use App\Domain\Entity\User;
interface UserRepositoryInterface {
public function findByEmail(string $email): ?User;
}
Шаг 5: Use Case (Application Layer)
// src/Application/UseCase/RegisterUser.php
namespace App\Application\UseCase;
use App\Domain\Entity\User;
use App\Domain\Repository\UserRepositoryInterface;
class RegisterUser {
private UserRepositoryInterface $repo;
public function __construct(UserRepositoryInterface $repo) {
$this->repo = $repo;
}
public function execute(string $email): User {
if ($this->repo->findByEmail($email)) {
throw new \Exception("User already exists");
}
$user = new User(uniqid(), $email);
// save to repository (not shown here)
return $user;
}
}
Шаг 6: Реализация репозитория (Infrastructure Layer)
// src/Infrastructure/Persistence/InMemoryUserRepository.php
namespace App\Infrastructure\Persistence;
use App\Domain\Entity\User;
use App\Domain\Repository\UserRepositoryInterface;
class InMemoryUserRepository implements UserRepositoryInterface {
private array $users = [];
public function findByEmail(string $email): ?User {
foreach ($this->users as $user) {
if ($user->getEmail() === $email) {
return $user;
}
}
return null;
}
public function save(User $user): void {
$this->users[] = $user;
}
}
Шаг 7: Входная точка (Framework Layer)
// public/index.php
use App\Application\UseCase\RegisterUser;
use App\Infrastructure\Persistence\InMemoryUserRepository;
require_once __DIR__ . '/../vendor/autoload.php';
$repo = new InMemoryUserRepository();
$useCase = new RegisterUser($repo);
try {
$user = $useCase->execute('test@example.com');
echo "User registered: " . $user->getEmail();
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
Clean Architecture в PHP позволяет проектировать приложения с чётким разделением обязанностей, снижая связанность компонентов и упрощая тестирование. Несмотря на то что PHP изначально создавался как язык для веба, он отлично справляется с реализацией архитектурных подходов, присущих крупным программным системам.
Такой подход особенно эффективен при построении долгоживущих и масштабируемых систем, требующих гибкости и поддержки на протяжении многих лет.
-
-
Михаил Русаков
Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.