ServiceLocator, давайте подумаем об этом в контексте ZF2

Согласно мысли Пиветты Марко, этот старый вопрос и мой ответ на другой вопрос

Я допрашивал себя о том, как лучше использовать наши службы в приложении Zend Framework 2.

На самом деле мы можем использовать ServiceLocatorAwareInterface сочетании с ServiceLocatorAwareTrait . С тем фактом, что в ZF3 сервисный локатор будет удален в контроллере. Возможно, они также удалят этот интерфейс или не будут советовать людям, которые его не используют, это имеет смысл.

Единственный способ, которым я вижу, как наши Услуги могут быть построены, это:

Не используйте ServiceLocator в своих Сервисах, используйте DependancyInjection.

Проблема в :

Некоторые проекты настолько велики, что у вас есть:

  • 15 классов услуг для одного рабочего процесса.
  • Класс обслуживания с 15 зависимостями.
  • Выберите свой кошмар …

Пример того, что вам может понадобиться в службе:

  • Верните formManager (вы не можете вызвать его в контроллере)
  • Возможно, вам нужно будет заставить ViewRenderer отображать шаблон перед возвратом строки HTML в представление через AJAX и ответ JSON;
  • Возможно, вам понадобится вернуть переводчика или любую услугу, которую вы хотите предоставить ZF2
  • Получите ваш менеджер объектов, если у вас есть несколько баз данных, добавьте счет здесь
  • Получите другие услуги, такие как MailService, ExportService, ImportService и так далее …
  • Если вам нужно загружать специфические сервисы, зависит от клиента (многоклиентский веб-сайт в BtoB … добавляет somes-сервисы, потому что вы не можете загрузить | вызов AbstractFactory)

Возможно, для некоторых из этих моментов их можно решить с помощью трюков, которые я не знаю.

Мой вопрос:

Является ли хорошей практикой иметь 15 или более зависимостей для одной службы и отказаться от ServiceLocator, в контроллерах, а также в сервисах?

Изменить комментарий

Для иллюстрации моей точки, я вставляю один из моих конструкторов:

 public function __construct( ToolboxService $toolboxService, EntityService $entityService, UserService $userService, ItemService $itemService, CriteriaService $criteriaService, Import $import, Export $export, PhpRenderer $renderer ) { $this->toolboxService = $toolboxService; $this->entityService = $entityService; $this->userService = $userService; $this->emOld = $this->toolboxService->getEmOld(); $this->emNew = $this->toolboxService->getEmNew(); $this->serviceLocator = $this->toolboxService->getServiceLocator(); $this->itemService = $itemService; $this->criteriaService = $criteriaService; $this->import = $import; $this->export = $export; $this->renderer = $renderer; $this->formManager = $this->toolboxService->getFormManager(); } 

Как вы можете видеть, ToolboxService – это объект с несколькими зависимостями. Эта служба находится в моей папке приложений и почти везде. У меня есть 2 менеджера объектов (подключение к 2 базам данных, но, возможно, скоро, мне понадобится третий …)

Вы можете видеть, что я использую serviceLocator через зависимость, поэтому эта служба не реализует ServiceLocatorAwareInterface . Если я не использую его, я лирировал, чтобы мой вызов AbstractFactory

 // Distribute somes orders depends on Clients $distributionClass = $this->serviceLocator->get(ucfirst($param->type)); if ($distributionClass instanceof DistributeInterface) { $distributionClass->distribute($orders, $key); } else { throw new \RuntimeException("invalid_type_provided", 1); } 

Solutions Collecting From Web of "ServiceLocator, давайте подумаем об этом в контексте ZF2"

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

При использовании ServiceLocator вы попадете в созданный экземпляр класса сервиса, где жесткие зависимости могут быть или не доступны через ServiceLocator . Это означает, что вам нужно написать всю дополнительную логику (проверить зависимости, исключить исключения) в случае, если зависимость не может быть разрешена из экземпляра ServiceLocator тот момент, когда вы его просите. Написание всего этого кода, вероятно, будет намного более трудоемким, чем инъекция 15 зависимостей, и, кроме того, логика будет загромождать всю вашу службу.

Кроме того, вам все равно нужно будет добавить все методы setter и getter, чтобы иметь возможность получать ваши сервисы от вашего ServiceLocator и сделать вашу службу проверкой.

ИМХО, вводя 15 зависимостей, меньше кода и проще поддерживать, а затем вводит экземпляр ServiceLocator .