Сервисы

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

По своей сути, сервисы, это самые обычные PHP объекты, но также зарегистрированные в системе в специальном *.services.yml файле. Объекты, зарегистрированные в виде сервисов, в некоторых случаях могут вызываться напрямую, как обычные объекты, но зачастую, это становится проблематичным из-за поддержки зависимостей.

Сервисы могут описывать зависимости, которые им необходимы. Данные зависимости передаются в конструктор объекта сервиса, и объект использует их по назначению. Если зависимость имеет свои зависимости, они также будут загружены, и переданы в нужный конструктор, нужного объекта. За подобное поведение отвечает Service Container, который хранит всю информацию о сервисах, и собирает из них объекты, готовые к использованию.

Преимущества и недостатки

Как и у всех подходов, есть всегда как плюсы, так и недостатки.

Плюсы от объявления объектов в виде сервисов:

  • Позволяет использовать Dependency Injection.
  • Конечный пользователь (разработчик) работает с сервисами через единый API.
  • Так как разработчики обращаются к объектам через сервисы, это позволяет заменять частично или целиком объекты сервисов, не нарушая целостность системы и не требует никаких изменений в кодовой базе где уже используются сервисы.
  • Это позволяет изменять, дорабатывать или полностью заменять объекты сервисов в собственных проектах, опять же, не нарушая целостность системы и не беспокоиться о том, что код, обращающийся к сервису сломается. До тех пор пока вы следуете интерфейсу оригинального сервиса, проект будет продолжать работать бесперебойно, не зависимо, какое название у объекта и неймспейс.
  • Обращение к объекту при помощи сервиса, инициализирует объект сервиса единожды, при первом обращении (по умолчанию, самый распространенный вариант), а при всех последующих, отдает уже инициализированный экземпляр. Это очень положительно сказывается на производительности и потреблении ресурсов.
  • Сервисы могут иметь метки, а другой код, находить все сервисы с определенной меткой и использовать их в нужный момент. Таким образом, сервисы могут быть частью какой-то коллекции, которые одновременно вызываются при определенных условиях. Вам, как разработчику, не придётся думать, как найти все объекты на проекте, которые отвечают каким-то признакам.

Недостатки от объявления объектов в виде сервисов:

  • Если ваш объект, нуждается в инициализации на каждое обращение, то использование сервисов в данном случае, может сделать обратный эффект, и снизить производительность. Но такие случаи крайне редкие.
  • Из-за возможности указывать зависимости, которые поступают в объект через конструктор, у вас может возникнуть проблема, что в объект поступает слишком много других объектов, которые могут понадобиться, а могут не понадобиться. Это усложняет поддержку подобных объектов, и может негативно сказаться на производительности.

Когда использовать сервисы

Исходя из преимуществ и недостатков, можно сделать вывод, что сервисы могут как помочь улучшить удобство работы и производительность проекта, так и навредить.

Решается это тем, что нужно правильно определять что нужно завернуть в сервис, а что оставить обычным объектом с классическим обращением по неймспейсу.

В общем случае, рекомендации будут следующие:

  • Если ваш объект, нуждается в функционале, который предоставляется сторонним сервисом — используйте сервис и указывайте необходимый(е) как зависимость вашего.
  • Если ваш объект самодостаточен, или вовсе состоит из статических методов (утилитарный класс, например Drupal\Component\Utility\Crypt), и не нуждается в других сервисах, то лучше не объявлять его в качестве сервиса.
  • Если ваш объект нуждается в инициализации каждый раз, когда он вызывается (например Value Object), то сервисы лучше избегать. Хоть они и поддерживают возможность создания экземпляра на каждое обращение к сервису, эта операция намного затратнее по ресурсам, нежели простое создание экземпляра объекта.

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

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

Ссылки

Помощь и обратная связь

Если вы обнаружили ошибку или хотите внести улучшения, и желаете внести изменения самостоятельно при помощи Pull Request
Если вы желаете предложить улучшение для этого документа

Обратиться за помощью

Если вы не нашли то что искали, воспользуйтесь поиском.

Если вам нужна помощь с чем-то конкретным, обратитесь к сообществу.