Каким способом правильнее разрешить зависимости класса?

Имеется класс "А" с методом "ab" (и многими другими). Метод "ab" генерирует результат, используя методы нескольких классов, в том числе методы класса "B".

Каким способом правильнее разрешить зависимости метода "ab" от класса "B"?

Какие я вижу способы (на примере Laravel) и их недостатки:
  1. Внедрение "B" через конструктор: если класс обрастет зависимостями, каждый раз при создании экземпляра класса будут инстанциироваться все зависимости, что как мне кажется, скажется на быстродействии/потреблении памяти
  2. Получать зависимость внутри метода, используя сервис-локатор (в случае Laravel это методы resolve, app()->make): при тестировании, для установки заглушек на зависимости, придется тратить много времени на настройку сервис-контейнера.
  3. Оборачивать пункт 2(получение зависимости через сервис-локатор) в отдельный метод-геттер (например, getMyService()), и при тестировании ставить заглушку на этот геттер: как-таковых недостатков пока не вижу.


Как считаете вы?
  • Вопрос задан
  • 1007 просмотров
Решения вопроса 3
lexxpavlov
@lexxpavlov
Программист, преподаватель
4. Передать B аргументом метода ab() (function ab(B $b))

Лучше первый способ. Если класс обрастет зависимостями, тогда можно подумать о рефакторинге. А вдруг не обрастёт?..

Но точнее вам никто не скажет, не посмотрев код - мало данных в тексте вопроса.
1) Как часто вызывается метод ab()? В каждом запросе? или в одном из сотни запросов?
2) используется ли B в других местах класса A?
3) Как передаются зависимости через конструктор?
new A(new B) или $b = new B; new A($b); new A($b); new A($b); или из контейнера? Ведь если B уже есть в контейнере, то передать в конструктор очень просто и быстро.
Ответ написан
Keanor
@Keanor
Ведущий разработчик
Тоже всегда использую вариант 1, он гарантирует что у если у вас есть инстанс класса, вы можете его полноценно использовать. Если же использовать мягкие зависимости то возможны ситуации когда объект есть, а зависимости не инициализированы, и ваш класс в некотором смысле становиться либо "зависимым" от фабрики, либо усложняется его использование необходимостью проверки наличия нужных зависимостей. Ведь у зависимостей класса тоже могут быть свои зависимости, у которых может отсутствовать что-то. И чем больше зависимостей, тем сложнее этим управлять.

Так-же большое кол-во аргументов в конструктор является неплохим призывом порефакторить.

Проблемы с памятью решаются сильно дешевле, чем время программистов на поиски ошибок.
Ответ написан
@justpusher
Я всегда использую вариант 1.
Чтобы не страдало быстродействие, конструкторы должны быть максимально лёгкими.
Возможно, вы и получите +0.01 секунду и +2МБ памяти, но это не должно вас беспокоить, ведь вы получаете понятный, гибкий и легко тестируемый код.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы