Во-первых, я хотел бы отделить подход к проектированию от концепции фреймворков. Внедрение зависимостей на самом простом и фундаментальном уровне - это просто:
Родительский объект предоставляет все зависимости, необходимые для дочернего объекта.
Вот и все. Обратите внимание, что для этого ничего не требуется интерфейсов, фреймворков, любого стиля внедрения и т. Д. Чтобы быть справедливым, я впервые узнал об этом шаблоне 20 лет назад. Это не ново.
Из-за того, что более 2 человек имеют путаницу по поводу термина «родитель» и «ребенок» в контексте внедрения зависимости:
- Родительским является объект , который создает и настраивает дочерний объект он использует
- Ребенок является компонентом , который предназначен для пассивного экземпляра. Т.е. он предназначен для использования любых зависимостей, предоставленных родителем, и не создает свои собственные зависимости.
Внедрение зависимостей - это шаблон для композиции объекта .
Почему интерфейсы?
Интерфейсы - это контракт. Они существуют, чтобы ограничить, насколько тесно могут быть связаны два объекта. Не всем зависимостям нужен интерфейс, но они помогают при написании модульного кода.
Когда вы добавляете концепцию модульного тестирования, у вас могут быть две концептуальные реализации для любого данного интерфейса: реальный объект, который вы хотите использовать в своем приложении, и макетированный или заглушенный объект, который вы используете для тестирования кода, который зависит от объекта. Одного этого может быть достаточно для интерфейса.
Почему рамки?
По сути, инициализация и предоставление зависимостей дочерним объектам могут быть пугающими, когда их много. Фреймворки предоставляют следующие преимущества:
- Автосвязь зависимостей к компонентам
- Настройка компонентов с какими-то настройками
- Автоматизация кода котельной плиты, чтобы вам не приходилось видеть его написанным в нескольких местах.
У них также есть следующие недостатки:
- Родительский объект - это «контейнер», и ничего в вашем коде
- Это усложняет тестирование, если вы не можете предоставить зависимости непосредственно в тестовом коде
- Это может замедлить инициализацию, поскольку она разрешает все зависимости, используя отражение и многие другие приемы.
- Отладка во время выполнения может быть более сложной, особенно если контейнер внедряет прокси между интерфейсом и фактическим компонентом, который реализует интерфейс (на ум приходит аспектно-ориентированное программирование, встроенное в Spring). Контейнер - это черный ящик, и он не всегда построен с какой-либо концепцией, облегчающей процесс отладки.
Все, что сказал, есть компромиссы. Для небольших проектов, в которых не так много движущихся частей, и нет особых причин использовать DI-фреймворк. Однако для более сложных проектов, в которых уже есть определенные компоненты, рамки могут быть оправданы.
Как насчет [случайной статьи в Интернете]?
Что насчет этого? Много раз люди могут переусердствовать, добавлять кучу ограничений и ругать вас, если вы не делаете «единственно верный путь». Там нет одного верного пути. Посмотрите, сможете ли вы извлечь из статьи что-нибудь полезное и игнорировать то, с чем вы не согласны.
Короче, подумай сам и попробуй.
Работа со "старыми головами"
Узнайте как можно больше. Со многими разработчиками, которые работают в свои 70 лет, вы обнаружите, что они научились не быть догматичными во многих вещах. У них есть методы, с которыми они работали на протяжении десятилетий, которые дают правильные результаты.
Я имел честь поработать с некоторыми из них, и они могут предоставить несколько откровенно честных отзывов, которые имеют большой смысл. И там, где они видят ценность, они добавляют эти инструменты в свой репертуар.