← Назад к вопросам

Какие знаешь архитектурные паттерны?

2.0 Middle🔥 252 комментариев
#Архитектура и паттерны

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Архитектурные паттерны в PHP Backend разработке

Архитектурные паттерны — это высокоуровневые шаблоны организации кода, которые определяют структуру приложения, взаимодействие компонентов и распределение ответственности. В отличие от шаблонов проектирования (design patterns), они решают проблемы на уровне всей системы. Вот ключевые архитектурные паттерны, которые я применял в PHP разработке:

1. Слоистая архитектура (Layered Architecture)

Наиболее распространённый подход в веб-разработке, где приложение разделяется на горизонтальные слои с чёткими обязанностями.

// Пример структуры в Laravel (упрощённо)
// Presentation Layer (Controllers)
class UserController {
    public function store(UserRequest $request, UserService $service) {
        $user = $service->create($request->validated());
        return response()->json($user, 201);
    }
}

// Business Layer (Services)
class UserService {
    private UserRepository $repository;
    
    public function create(array $data): User {
        // Бизнес-логика
        $user = new User($data);
        $this->repository->save($user);
        return $user;
    }
}

// Data Access Layer (Repositories)
class UserRepository {
    public function save(User $user): void {
        $user->save();
    }
}

Преимущества: простота понимания, чёткое разделение ответственности, лёгкость тестирования.
Недостатки: может приводить к "божественным" классам, если бизнес-логика сосредотачивается в одном слое.

2. Архитектура на основе событий (Event-Driven Architecture)

Основана на генерации и обработке событий, что обеспечивает слабую связанность компонентов.

// Пример с Symfony EventDispatcher
class OrderService {
    private $eventDispatcher;
    
    public function createOrder(array $data): void {
        // Создание заказа
        $order = new Order($data);
        
        // Генерация события
        $this->eventDispatcher->dispatch(
            new OrderCreatedEvent($order),
            'order.created'
        );
    }
}

// Обработчик события
class SendOrderConfirmationListener {
    public function onOrderCreated(OrderCreatedEvent $event): void {
        // Отправка email подтверждения
        $order = $event->getOrder();
        $this->mailer->sendConfirmation($order);
    }
}

Применение: системы с асинхронными операциями, микросервисы, сложные бизнес-процессы.

3. Гексагональная архитектура (Hexagonal/Ports & Adapters)

Альтернатива слоистой архитектуре, где ядро приложения (домен) изолировано от внешних зависимостей.

Ключевые элементы:

  • Порты (Ports): интерфейсы, определяющие контракты взаимодействия
  • Адаптеры (Adapters): реализации портов для конкретных технологий
  • Ядро (Core): чистая бизнес-логика без внешних зависимостей
// Порты (интерфейсы в ядре)
interface UserRepositoryInterface {
    public function save(User $user): void;
    public function findById(int $id): ?User;
}

// Ядро приложения (чистая бизнес-логика)
class UserRegistrationService {
    private UserRepositoryInterface $repository;
    
    public function register(User $user): void {
        // Валидация бизнес-правил
        if ($user->isValid()) {
            $this->repository->save($user);
        }
    }
}

// Адаптер для базы данных (внешний слой)
class DoctrineUserRepository implements UserRepositoryInterface {
    private EntityManager $em;
    
    public function save(User $user): void {
        $this->em->persist($user);
        $this->em->flush();
    }
}

Преимущества: полная изоляция бизнес-логики, лёгкая замена инфраструктуры, повышенная тестируемость.

4. CQRS (Command Query Responsibility Segregation)

Разделение моделей для операций чтения и записи, что особенно эффективно в сложных системах.

// Command (запись)
class CreateUserCommand {
    public function __construct(
        public string $email,
        public string $name
    ) {}
}

class CreateUserHandler {
    public function handle(CreateUserCommand $command): void {
        // Логика создания пользователя
        $user = new User($command->email, $command->name);
        $this->repository->save($user);
    }
}

// Query (чтение)
class GetUserQuery {
    public function __construct(public int $userId) {}
}

class GetUserHandler {
    public function handle(GetUserQuery $query): UserDto {
        // Возвращаем DTO, а не доменную модель
        return $this->userReadModel->find($query->userId);
    }
}

Сценарии применения: системы с высокой нагрузкой на чтение, сложные отчеты, событийные системы.

5. Микросервисная архитектура

Разделение приложения на небольшие независимые сервисы, каждый со своей базой данных и бизнес-логикой.

Характеристики:

  • Каждый микросервис решает одну бизнес-задачу
  • Независимое развертывание и масштабирование
  • Общение через API (REST, gRPC, сообщения)

Критерии выбора архитектуры

При выборе архитектурного паттерна я руководствуюсь следующими критериями:

  • Сложность домена: для простых CRUD-приложений достаточно слоистой архитектуры, для сложной бизнес-логики — гексагональной или событийной
  • Масштабируемость: микросервисы и CQRS лучше подходят для высоконагруженных систем
  • Гибкость требований: событийная архитектура позволяет легко добавлять новую функциональность
  • Команда и сроки: сложные архитектуры требуют больше времени на разработку и опытной команды

Практические рекомендации

В реальных проектах я часто комбинирую подходы:

  • Основная структура — гексагональная архитектура для изоляции домена
  • CQRS для сложных отчетов и аналитики
  • Событийная система для интеграции между модулями
  • Слоистая организация внутри отдельных компонентов

Ключевой принцип — начинать с простой архитектуры и усложнять её только при появлении объективных потребностей, следуя принципу YAGNI (You Ain't Gonna Need It). Современные PHP-фреймворки (Laravel, Symfony) предоставляют инструменты для реализации всех перечисленных паттернов, что делает их практичное применение вполне доступным.