Согласно мысли Пиветты Марко, этот старый вопрос и мой ответ на другой вопрос
Я допрашивал себя о том, как лучше использовать наши службы в приложении Zend Framework 2.
На самом деле мы можем использовать ServiceLocatorAwareInterface
сочетании с ServiceLocatorAwareTrait
. С тем фактом, что в ZF3 сервисный локатор будет удален в контроллере. Возможно, они также удалят этот интерфейс или не будут советовать людям, которые его не используют, это имеет смысл.
Единственный способ, которым я вижу, как наши Услуги могут быть построены, это:
Не используйте ServiceLocator в своих Сервисах, используйте DependancyInjection.
Проблема в :
Некоторые проекты настолько велики, что у вас есть:
Пример того, что вам может понадобиться в службе:
Возможно, для некоторых из этих моментов их можно решить с помощью трюков, которые я не знаю.
Мой вопрос:
Является ли хорошей практикой иметь 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); }
Предположим, вы ServiceLocator
экземпляр ServiceLocator
. Нет гарантии, что ServiceLocator
действительно содержит ваши жесткие зависимости, тем самым нарушая шаблон DI. При использовании инъекции зависимостей конструктора вы уверены, что все необходимые службы действительно доступны. Если нет, то построение службы просто потерпит неудачу.
При использовании ServiceLocator
вы попадете в созданный экземпляр класса сервиса, где жесткие зависимости могут быть или не доступны через ServiceLocator
. Это означает, что вам нужно написать всю дополнительную логику (проверить зависимости, исключить исключения) в случае, если зависимость не может быть разрешена из экземпляра ServiceLocator
тот момент, когда вы его просите. Написание всего этого кода, вероятно, будет намного более трудоемким, чем инъекция 15 зависимостей, и, кроме того, логика будет загромождать всю вашу службу.
Кроме того, вам все равно нужно будет добавить все методы setter и getter, чтобы иметь возможность получать ваши сервисы от вашего ServiceLocator
и сделать вашу службу проверкой.
ИМХО, вводя 15 зависимостей, меньше кода и проще поддерживать, а затем вводит экземпляр ServiceLocator
.