Какие шаблоны проектирования используются в Laravel?
Laravel построен как фреймворк, который активно использует шаблоны проектирования для организации кода, масштабируемости и разделения ответственности. Понимание этих паттернов позволяет лучше проектировать архитектуру приложений, правильно использовать встроенные механизмы Laravel и избегать избыточной связности кода.
Ниже рассмотрены ключевые шаблоны проектирования, которые применяются в Laravel и его экосистеме.
MVC (Model-View-Controller)
Laravel основан на архитектурном шаблоне MVC.
Роли компонентов:
- Model — работа с данными и бизнес-логикой (чаще всего через Eloquent ORM)
- View — представление данных (Blade-шаблоны)
- Controller — обработка запросов и координация между Model и View
MVC разделяет ответственность, что делает код предсказуемым и тестируемым.
Пример:
class UserController extends Controller
{
public function show($id)
{
$user = User::findOrFail($id);
return view("users.show", compact("user"));
}
}
Dependency Injection (DI)
Dependency Injection является одним из ключевых принципов Laravel. Он реализуется через Service Container.
Laravel автоматически внедряет зависимости в контроллеры, сервисы и middleware.
class UserService
{
public function __construct(private UserRepository $repo) {}
}
Laravel самостоятельно разрешает зависимости через контейнер.
Service Container (IoC Container)
Service Container реализует принцип Inversion of Control (IoC). Он управляет созданием объектов и их зависимостей.
Основные возможности:
- автоматическое разрешение зависимостей
- регистрация bindings
- singleton-объекты
- фабрики сервисов
Пример регистрации:
app()->bind(UserRepository::class, EloquentUserRepository::class);
Singleton
Laravel активно использует паттерн Singleton через Service Container.
Singleton гарантирует, что класс имеет только один экземпляр в рамках приложения.
Пример:
app()->singleton(Logger::class, function () {
return new Logger();
});
Используется для:
- логирования
- конфигурации
- сервисов с общим состоянием
Facade
Facade в Laravel — это паттерн, который предоставляет статический интерфейс к объектам из Service Container.
Пример:
use Illuminate\Support\Facades\Cache;
Cache::put("key", "value", 600);
Важно понимать: Facade не является статическим классом. Это прокси к объекту в контейнере.
Преимущества:
- удобный синтаксис
- скрытие сложной логики
- быстрый доступ к сервисам
Factory
Factory используется для создания объектов, особенно моделей в тестировании и сидерах.
Пример:
User::factory()->count(10)->create();
Laravel Factories позволяют:
- быстро генерировать тестовые данные
- изолировать логику создания объектов
- упрощать тестирование
Repository Pattern
Repository Pattern не является обязательной частью Laravel, но часто применяется в архитектуре приложений на Laravel.
Он отделяет бизнес-логику от слоя доступа к данным.
Пример:
interface UserRepository
{
public function findById(int $id);
}
class EloquentUserRepository implements UserRepository
{
public function findById(int $id)
{
return User::find($id);
}
}
Преимущества:
- тестируемость
- возможность заменить источник данных
- изоляция Eloquent от бизнес-логики
Observer
Observer активно используется в Eloquent Models.
Он позволяет реагировать на события модели:
- created
- updated
- deleted
- saving
Пример:
class UserObserver
{
public function created(User $user)
{
Log::info("User created: " . $user->id);
}
}
Регистрация:
User::observe(UserObserver::class);
Event Dispatcher (Publish-Subscribe)
Laravel реализует мощную систему событий и слушателей.
Это реализация паттерна Observer на уровне системы.
Пример события:
event(new UserRegistered($user));
Listener:
class SendWelcomeEmail
{
public function handle(UserRegistered $event)
{
Mail::to($event->user->email)->send(new WelcomeMail());
}
}
Преимущества:
- слабая связанность компонентов
- расширяемость системы
- асинхронная обработка (через queues)
Strategy Pattern
Laravel использует Strategy Pattern в различных компонентах, например:
- система файловых хранилищ (local, s3, ftp)
- платежные драйверы (через сторонние пакеты)
- логирование каналов
Пример:
Storage::disk("s3")->put("file.txt", $content);
Разные реализации выбираются во время выполнения.
Pipeline (Middleware)
Middleware в Laravel реализует паттерн Pipeline.
Запрос проходит через цепочку обработчиков.
Пример:
Route::middleware(["auth", "throttle:60,1"])->group(function () {
Route::get("/dashboard", DashboardController::class);
});
Каждый middleware:
- получает запрос
- может изменить его
- может остановить выполнение
Это классическая цепочка обработки (Chain of Responsibility + Pipeline).
Command Pattern (Artisan)
Artisan команды реализуют Command Pattern.
Каждая команда инкапсулирует действие:
php artisan make:controller UserController
Создание собственной команды:
class SendEmails extends Command
{
public function handle()
{
// логика выполнения
}
}
Преимущества:
- изоляция операций
- повторное использование
- возможность планирования через scheduler
Template Method (внутри фреймворка)
Laravel использует Template Method в базовых классах, например:
- Controller
- Command
- Job
Базовый класс определяет структуру выполнения, а наследники реализуют детали.
Active Record (Eloquent ORM)
Eloquent реализует Active Record pattern.
Модель одновременно:
- представляет данные
- управляет их сохранением
- содержит бизнес-логику
Пример:
$user = new User();
$user->name = "John";
$user->save();
Плюсы:
- простота использования
- быстрый CRUD
- тесная интеграция с фреймворком
Минусы:
- может приводить к смешению ответственности при неправильной архитектуре
Итог
Laravel использует комбинацию классических и современных шаблонов проектирования:
- MVC для архитектуры приложения
- IoC Container и Dependency Injection для управления зависимостями
- Facade для упрощения доступа к сервисам
- Observer и Event Dispatcher для реактивной архитектуры
- Repository и Factory для структурирования данных и тестирования
- Pipeline (Middleware) для обработки запросов
- Command Pattern для консольных операций
- Strategy для заменяемых реализаций
- Active Record для ORM
Эта комбинация делает Laravel гибким фреймворком, который позволяет строить как простые приложения, так и сложные распределенные системы без изменения базовой архитектуры.
- 27.06.2026