[Из песочницы] Внедрение зависимостей через поля — плохая практика
Комментарии (7)
1 августа 2017 в 15:25
0↑
↓
Одна из ключевых идей DI-фреймворков заключается в том, что управляемый класс не должен зависеть от конкретного используемого контейнера.… snip… Если нет завязки на контейнер, вы можете использовать класс как управляемый или неуправляемый, или даже переключиться на другой DI-фреймворк.
При этом, в реальности это всё равно не так. Вы можете менять контейнер, например, в пределах разных имплементаций CDI, но для перескакивания на Guice или Spring часто придётся править аннотации в этих классах. Spring, вроде, имел некоторый уровень совместимости с
javax.inject
, но умел далеко не всё. Как сейчас — не знаю.1 августа 2017 в 15:33
0↑
↓
Upd: дочитал статью и увидел, что спринговцы «починили» кусок: неявное внедрение через конструктов (без использования
@Autowired
), т. е. если класс имеет ровно один конструктор, то он может быть не завязан на classpath spring’а.
1 августа 2017 в 15:43
0↑
↓
Но суть же не в том, что инъекция через поля — это зло, скорее злом является чрезмерно сложный класс. А если класс лаконичен и не требует рефакторинга, то будет ли проблемой заинжектить 1–2 поля через Autowired?1 августа 2017 в 15:49
+1↑
↓
А в тесте вы как моки будете инжектить в эти поля? DI, он не в последнюю очередь для упрощения тестирования, а когда вы инжектити зависимость в приватное поле — это почти тоже самое, что создать там зависимость через new.1 августа 2017 в 15:55
0↑
↓
А в чем проблема заинжектить моки в поля? InjectMocks, MockitoAnnotations.initMocks (). Те же моки уйдут в тестовый бин как через поля, так и через сеттеры1 августа 2017 в 16:08
0↑
↓
Поправочка: проблема в том, что это будет требовать запуска DI-контейнера, что не всегда нужно.
1 августа 2017 в 16:01 (комментарий был изменён)
+1↑
↓
Инжект в приватное поле «привязывает» класс к IoC-контейнеру — объект такого класса нельзя создать иначе чем с его помощью; при обычном создании через new он просто не будет работать. Наличие «магии» — само по себе не плохо, плохо когда «магия» становится обязательной.
В то же время, если класс является точкой входа в пользовательский код и принципиально создается только кодом платформы — то в инъекции через поля нет ничего плохого. Не знаю как в мире java, но в ASP.NET MVC такими классами являются виды и контроллеры — для них строгая инъекция через конструктор избыточна (а для видов — и вовсе невозможна).