Featured image of post Каковы логические различия между bind(), singleton(), scoped() и instance() в Laravel? В каких сценариях их можно использовать?

Каковы логические различия между bind(), singleton(), scoped() и instance() в Laravel? В каких сценариях их можно использовать?

Каковы логические различия между bind(), singleton(), scoped() и instance() в Laravel? В каких сценариях их можно использовать?

Сравнение методов привязки объектов в сервис-контейнере Laravel

Метод bind() singleton() scoped() instance()
Описание Создает новый экземпляр каждый раз при разрешении. Создает только один экземпляр и возвращает тот же экземпляр в последующих запросах. Создает только один экземпляр в рамках каждого жизненного цикла запроса/задачи; он очищается после завершения запроса. Привязывает существующий экземпляр к контейнеру и возвращает этот экземпляр каждый раз при разрешении.
Плюсы - Свежий экземпляр для каждого запроса, нет проблем с общим состоянием
- Чистое использование памяти
- Подходит для логики, требующей независимого состояния
- Может предоставлять уникальную конфигурацию для каждого запроса
- Экономит системные ресурсы, создавая экземпляр только один раз
- Обеспечивает согласованность состояния
- Подходит для совместного использования конфигурации и ресурсов
- Лучшая производительность при высокой конкурентности
- Баланс использования памяти и общего состояния
- Совместное использование состояния внутри запроса, но изоляция между запросами
- Подходит для сценариев веб-запросов
- Полный контроль над временем создания экземпляра
- Можно предварительно настроить состояние экземпляра
- Подходит для сервисов, требующих определенной конфигурации
Минусы - Требует больше системных ресурсов для повторного создания экземпляров
- Может повлиять на производительность при высокой конкурентности
- Не подходит для сценариев, требующих общего состояния
- Может вызвать проблемы с производительностью, так как каждый раз создается новый экземпляр.
- Общее состояние может привести к трудноотслеживаемым ошибкам
- Не подходит для сценариев, требующих независимого состояния
- Использование памяти сохраняется до завершения программы
- Тестирование требует особого внимания к сбросу состояния
- Если экземпляр содержит состояние, это может вызвать неожиданное поведение.
- Может вызвать проблемы в длительных задачах
- Требует понимания жизненного цикла запроса
- Не подходит для команд CLI
- Менее гибкий
- Нельзя динамически настраивать конфигурацию экземпляра
- Может занимать память при запуске
- Не подходит для случаев, требующих ленивой загрузки или нескольких экземпляров.
Сценарий использования Для краткосрочных сервисов или классов, требующих независимого состояния. Для глобально общих сервисов, таких как логгеры или менеджеры конфигурации. Для сервисов, которым необходимо поддерживать состояние внутри запроса, но не между запросами, таких как соединения с базой данных. Когда у вас уже есть экземпляр и вы хотите использовать его повторно, например, общий объект конфигурации.
Пример Когда у вас есть класс Product и вы хотите создавать новый экземпляр Product каждый раз, когда запрашиваются разные данные о продукте. Когда у вас есть класс Logger и вы хотите, чтобы все операции записи логов использовали один и тот же экземпляр для поддержания согласованности. Когда у вас есть класс ShoppingCart и вам нужно разделить состояние корзины покупок в рамках одного запроса. Когда у вас есть класс DatabaseConfig и вам нужно установить параметры соединения при запуске приложения.

Примеры

Использование bind()

$this->app->bind('Product', function () {
 return new Product();
});

Каждый раз при вызове app('Product') возвращается новый экземпляр Product.

Использование singleton()

$this->app->singleton('Logger', function () {
 return new Logger();
});

Каждый раз при вызове app('Logger') возвращается тот же экземпляр Logger.

Использование scoped()

$this->app->scoped(Transistor::class, function (Application $app) {
    return new Transistor($app->make(PodcastParser::class));
});

Разделяет один и тот же экземпляр в рамках одного жизненного цикла запроса; разные запросы будут создавать новые экземпляры.

Использование instance()


$service = new Transistor(new PodcastParser);
 
$this->app->instance(Transistor::class, $service);

Привязывает существующий экземпляр напрямую к контейнеру.

Резюме

Laravel в настоящее время может применяться во многих различных типах сценариев, таких как веб-запросы, команды CLI, задачи очереди, команды консоли и т. д.

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

Reference

All rights reserved,未經允許不得隨意轉載
Создано при помощи Hugo
Тема Stack, дизайн Jimmy