🧱 Суть

Паттерны разработки (Design Patterns) – это готовые, проверенные временем способы решения часто встречающихся задач.

Они помогают:

  • избежать дублирования кода
  • сделать архитектуру понятнее
  • упростить расширение приложения
  • разделить ответственность между классами

Большинство современных PHP-фреймворков (Laravel, Symfony и др.) активно используют паттерны проектирования.

📦 Проблема

Без понятной структуры логика приложения быстро смешивается.

Например:

Controller

SQL-запросы

HTTP-запросы

Отправка почты

Бизнес-логика

Такой код сложно:

  • тестировать
  • изменять
  • повторно использовать

✅ Решение

Разделять ответственность между отдельными классами и использовать распространённые паттерны проектирования.

На практике чаще всего встречаются:

  • Repository
  • Service
  • Factory
  • Singleton
  • Dependency Injection

💻 Код

Repository

Repository отвечает за работу с источником данных.

Например:

Controller

Repository

Database

Вместо:

$user = PDO...

контроллер использует:

$userRepository->find($id);

Repository скрывает детали работы с базой данных.

Service

Service содержит бизнес-логику приложения.

Например:

Controller

UserService

Repository

Контроллер не знает, как именно создаётся пользователь.

Он вызывает:

$userService->create($data);

Вся логика находится внутри сервиса.

Factory

Factory отвечает за создание объектов.

Вместо:

$mail = new MailService();

используют:

$mail = MailFactory::create();

Factory особенно полезен, если создание объекта требует сложной настройки.

Dependency Injection (DI)

Dependency Injection – передача зависимостей извне.

Плохо:

class UserService
{
    private UserRepository $repository;
 
    public function __construct()
    {
        $this->repository = new UserRepository();
    }
}

Лучше:

class UserService
{
    public function __construct(
        private UserRepository $repository
    ) {}
}

Теперь класс легче:

  • тестировать
  • расширять
  • заменять зависимости

Singleton

Singleton гарантирует существование только одного экземпляра объекта.

Например:

Database

Один экземпляр

Используется редко и только в специальных случаях.

Во многих современных проектах вместо Singleton предпочитают Dependency Injection.

MVC

Большинство PHP-фреймворков используют архитектуру MVC.

Controller

Model

Database
 
Controller

View

Где:

  • Model – данные
  • View – отображение
  • Controller – обработка запросов

DTO (Data Transfer Object)

DTO используется для передачи данных между слоями приложения.

Например:

class UserDto
{
    public function __construct(
        public string $name,
        public string $email,
    ) {}
}

Вместо передачи массива:

[
    'name' => 'Alex',
    'email' => 'alex@test.com'
]

используется объект с чётко определённой структурой.

Strategy

Strategy позволяет менять алгоритм без изменения остального кода.

Например:

Оплата

Карта
PayPal
Криптовалюта

Все способы оплаты реализуют один интерфейс, а приложение выбирает нужную стратегию во время выполнения.

Adapter

Adapter позволяет работать с несовместимыми интерфейсами.

Например:

Старый API

Adapter

Новое приложение

Используется при интеграции со сторонними сервисами или устаревшим кодом.

Facade

Facade предоставляет простой интерфейс к сложной системе.

Вместо:

Service A
Service B
Service C

используют:

$mailFacade->send();

Фасад сам вызывает необходимые сервисы.

Builder

Builder помогает поэтапно создавать сложные объекты.

Например:

$query = $builder
    ->select('*')
    ->from('users')
    ->where('id = 1')
    ->build();

Такой подход широко используется в SQL Query Builder’ах и ORM.

Частые ошибки

Использовать паттерны без необходимости

Плохо:
Создавать десятки классов ради очень простого приложения.

Паттерны должны упрощать код, а не усложнять его.

Смешивать ответственность

Плохо:

Controller

SQL

Бизнес-логика

HTTP

Лучше разделить обязанности между Controller, Service и Repository.

Создавать зависимости через new

Плохо:

new UserRepository();

внутри каждого класса.

Лучше использовать Dependency Injection.

Использовать Singleton везде

Singleton часто приводит к сильной связанности компонентов.

В современных проектах обычно предпочтительнее Dependency Injection и контейнер зависимостей.

Дублировать бизнес-логику

Если одинаковая логика встречается в нескольких контроллерах, её следует вынести в сервис.

🎯 Вывод

  • Паттерны помогают строить понятную и расширяемую архитектуру
  • В PHP чаще всего используются Repository, Service и Dependency Injection
  • MVC разделяет приложение на модель, представление и контроллер
  • Factory, Builder, Adapter и Facade решают специализированные задачи
  • Паттерны стоит использовать только там, где они действительно упрощают код
  • Современные PHP-фреймворки активно используют большинство этих подходов

🔗 Связано