[Из песочницы] Внедрение зависимостей через поля — плохая практика

Комментарии (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 такими классами являются виды и контроллеры — для них строгая инъекция через конструктор избыточна (а для видов — и вовсе невозможна).

© Habrahabr.ru