Включение зависимости: следует ли использовать фреймворк?

Недавно я работал над проектом Python, в котором мы интенсивно вливали инъекцию (потому что нам нужно, чтобы приложение проверялось), но мы не использовали фреймворк. Время от времени было немного утомительно подключать все зависимости вручную, но в целом он отлично работал.

Когда объект должен был быть создан в нескольких местах, у нас просто была функция (иногда метод класса этого объекта), чтобы создать производственный экземпляр. Эта функция вызывается всякий раз, когда нам нужен этот объект.

В тестах мы сделали то же самое: если несколько раз нам нужно было создать «тестовую версию» объекта (т. е. реальный экземпляр, поддерживаемый макетными объектами), у нас была функция для создания этого теста -версия "класса, который будет использоваться в тестах.

Как я уже сказал, в целом это работало нормально.

Теперь я вхожу в новый Java-проект, и мы решаем, следует ли использовать структуру DI или делать DI вручную (как в предыдущем проекте).

Пожалуйста, объясните, как работать с каркасом DI будет отличаться, и в каких манерах это лучше или хуже, чем ручная «ванильная» инъекция зависимости.

Изменить: я также хотел бы добавить к вопросу: вы видели какой-либо проект «профессионального уровня», который делает DI вручную, без рамки?

24 голоса | спросил Aviv Cohn 14 Maypm16 2016, 22:44:16

9 ответов


19

Ключом контейнеров DI является абстракция . Контейнеры DI отражают эту проблему дизайна для вас. Как вы можете догадаться, это оказывает заметное влияние на код, часто переводится на меньшее количество конструкторов, сеттеров, фабрик и строителей. В результате они делают ваш код более слабо связанным (из-за базового IoC ), чище и проще. Хотя и не без затрат.

Фон

Несколько лет назад такая абстракция требовала от нас писать различные конфигурационные файлы ( декларативное программирование ). Было фантастически видеть, что количество LOC существенно уменьшилось, но в то время как LOCS уменьшилось, количество файлов конфигурации немного увеличилось. Для средних или небольших проектов это не было проблемой вообще, но для более крупных проектов, чтобы «сборка кода» разбросана на 50% между кодом и дескрипторами XML, стала болью в ... Тем не менее главная проблема заключалась в самой парадигме. Это было довольно негибким, потому что дескрипторы оставили мало места для настроек.

Парадигма постепенно переместилась в соглашение по настройке , которая обрабатывает файлы конфигурации для аннотации или атрибуты. Он помогает нам сделать код более чистым и простым, обеспечивая при этом гибкость, которую не может иметь XML.

Возможно, это самое значительное отличие в отношении того, как вы работали до сих пор. Меньше кода и больше магии.

С нижней стороны ...

Консолидация конфигурации делает абстракцию настолько тяжелой, что вы едва знаете, как она работает. Иногда кажется волшебным, и здесь возникает еще один недостаток. Как только вы работаете, многие разработчики не заботятся о том, как это работает.

Это препятствие для тех, кто изучил DI с контейнерами DI. Они не полностью понимают важность шаблонов проектирования, передовой практики и принципов, которые были абстрагированы контейнером. Я спросил разработчиков, были ли они ознакомлены с DI и его преимуществами, и они ответили: - Да, я использовал Spring IoC -. (Что, черт возьми, это значит?!?)

Можно согласиться или нет с каждым из этих «недостатков». По моему скромному мнению, нужно знать, что происходит в вашем проекте. В противном случае мы не имеем полного понимания этого. Также необходимо знать, что такое DI, и иметь представление о том, как его реализовать, это плюс, чтобы рассмотреть.

На стороне плюса ...

Одно слово производительность . Рамки позволяют сосредоточиться на том, что действительно важно. Бизнес приложения.

Несмотря на отмеченные недостатки, для многих из нас (работа которых обусловлена ​​предельными сроками и затратами) эти инструменты являются неоценимым ресурсом. На мой взгляд, это должен быть наш главный аргумент в пользу внедрения контейнеров DI. Производительность .

Тестирование

Если мы реализуем чистые DI или контейнеры, тестирование не будет проблемой. Наоборот. Одни и те же контейнеры часто предоставляют нам издевательства над модульным тестированием из коробки. В течение многих лет я использовал свои тесты в качестве термометров. Они говорят мне, сильно ли я полагаюсь на контейнеры. Я говорю это, потому что эти контейнеры могут инициализировать частные атрибуты без сеттеров или конструкторов. Они могут вводить компоненты практически в любом месте!

Звучит соблазнительно? Быть осторожен! Не попадайте в ловушку!

Предложения

Если вы решите внедрить контейнеры, я настоятельно рекомендую придерживаться хороших практик. Продолжайте внедрять конструкторы, сеттеры и интерфейсы. Использовать фреймворк /контейнер для использования . Это упростит миграцию в другую структуру или удалит ее. Это может значительно снизить зависимость от контейнера.

Относительно этогопрактика:

Когда использовать контейнеры DI

Мой ответ будет предвзятым по собственному опыту, который в основном относится к контейнерам DI (как я уже говорил, я в значительной степени сосредоточен на производительности, поэтому мне никогда не приходилось требовать чистого DI).

Я думаю, вы найдете интересный статью Марка Симана об этой теме , который также отвечает на вопрос о как реализовать чистый DI .

Наконец, если бы мы говорили о Java, я бы сначала рассмотрел JSR330 - Инъекция зависимостей .

Подведение итогов

Преимущества :

  • Сокращение затрат и экономия времени. Производительность.
  • Меньшее количество компонентов.
  • Код становится проще и чище.

Недостатки :

  • DI передается третьим лицам. Мы должны знать об их компромиссах, сильных и слабых сторонах.
  • Кривая обучения.
  • Они быстро заставляют вас забыть хорошие привычки.
  • Увеличение зависимостей проекта (больше libs)
  • Контейнеры на основе отражения требуют больше ресурсов (памяти). Это важно, если мы ограничены ресурсами.

Различия с чистым DI :

  • Меньше кода и больше файлов конфигурации или аннотаций.
ответил Laiv 15 Mayam16 2016, 00:24:48
10

По моему опыту, структура инъекций зависимостей приводит к ряду проблем. Некоторые из проблем будут зависеть от структуры и оснастки. Там могут быть методы, которые смягчают проблемы. Но это те проблемы, которые я ударил.

Неглобальные объекты

В некоторых случаях вы хотите ввести глобальный объект: объект, который будет иметь только один экземпляр в вашем запущенном приложении. Это может быть MarkdownToHtmlRendererer, a DatabaseConnectionPool , адрес для вашего сервера api и т. д. В этих случаях приложения для инъекций зависимостей работают очень просто, вы просто добавляете необходимую зависимость к своему конструктору и получаете его.

Но что относительно объектов, которые не являются глобальными? Что делать, если вам нужен пользователь для текущего запроса? Что делать, если вам нужна активная транзакция базы данных? Что делать, если вам нужен элемент HTML, соответствующий div, который содержит форму, в которой находится текстовое поле, которое только что вызвало событие?

Решение, которое я видел, используемое каркасами DI, является иерархическим инжектором. Но это делает модель инъекции более сложной. Становится сложнее понять, что будет вводиться с какого уровня иерархии. Трудно определить, будет ли данный объект существовать для каждого приложения, для каждого пользователя, для каждого запроса и т. Д. Вы уже не можете просто добавлять свои зависимости и работать.

Библиотеки

Часто вам нужно иметь библиотеку многоразового кода. Это также будет включать инструкции по созданию объектов из этого кода. Если вы используете инфраструктуру инъекции зависимостей, в нее обычно входят правила привязки. Если вы хотите использовать библиотеку, вы добавляете к ней свои правила привязки.

Однако могут возникнуть различные проблемы. Вы можете оказаться в том же классе, связанном с различными реализациями. Библиотека может ожидать, что определенные привязки будут существовать. Библиотека может переопределить некоторые привязки по умолчанию, заставляя ваш код делать странную вещь. Ваш код может переопределить привязку по умолчанию, в результате чего код библиотеки будет делать странные вещи.

Скрытая сложность

Когда вы вручную пишете фабрики, вы понимаете, как зависимости приложения совпадают. Когда вы используете инфраструктуру инъекции зависимостей, вы этого не видите. Вместо этого объекты, как правило, растут все больше зависимостей, пока рано или поздно все не будет в значительной степени зависеть.

Поддержка IDE

Ваша среда IDE, вероятно, не будет понимать структуру инъекций зависимостей. С помощью ручных фабрик вы можете найти всех вызывающих элементов конструктора, чтобы выяснить все места, которые объект мог бы построить. Но он не найдет вызовы, созданные каркасом DI.

Заключение

Что мы получаем из рамки инъекции зависимостей? Мы должны избегать некоторых простодушных шаблонов, необходимых для создания объектов. Я все для того, чтобы избавиться от простодушного шаблона. Однако поддерживать простой мысленный шаблон легко. Если мы собираемся заменить этот шаблон, мы должны настаивать на замене его чем-то более простым. Из-за различных проблем, о которых я говорил выше, я не думаю, что рамки (по крайней мере, они стоят) соответствуют законопроекту.

ответил Winston Ewert 16 Mayam16 2016, 07:25:34
3

Требуется ли инъекция зависимости Java + = фреймворк?

Нет.

Что мне предлагает каркас DI?

Конструкция объекта происходит на языке, который не является Java.


Если заводские методы достаточно хороши для ваших нужд, вы можете сделать DI в полной версии java framework в 100% аутентичном java-сообществе. Если ваши потребности выходят за рамки этого, у вас есть другие варианты.

Шаблоны дизайна Gang of Four выполняют множество замечательных вещей, но всегда имели слабые стороны, когда дело доходило до шаблонов создания. Здесь у Java есть некоторые недостатки. Основы DI действительно помогают с этой слабостью создания больше, чем с фактическими инъекциями. Вы уже знаете, как это сделать без них. Насколько они хороши, вы будете зависеть от того, какую помощь вам потребуется при строительстве объекта.

Существует множество шаблонов творчества, которые появились после «Банды четырех». Разработчик Josh Bloch - замечательный хак, в котором нет именованных параметров java. Кроме того, это iDSL-сборщики, которые предлагают большую гибкость. Но каждый из них представляет собой значительную работу и шаблон.

Рамки могут спасти вас от некоторых из этих скуки. Они не лишены недостатков. Если вы не будете осторожны, вы можете оказаться зависимыми от фреймворка. Попробуйте переключить фреймворки после использования одного и убедитесь сами. Даже если вы каким-то образом сохраните родословную xml или аннотации, вы можете в конечном итоге поддержать то, что по существу два языка, которые вы должны упомянуть бок о бок, когда рекламируете задания по программированию.

Прежде чем вы будете слишком влюблены в возможности каркасов DI, потребуется некоторое время и исследуйте другие структуры, которые дают вам возможности, которые в противном случае вам могут показаться, что вам нужна инфраструктура DI. Многие из них выходят за рамки простого DI . Рассмотрим: Ломбок , AspectJ и slf4J . Каждый из них накладывается на некоторые рамки DI, но каждый работает отлично самостоятельно.

Если тестирование действительно является движущей силой этого, загляните в: jUnit (любой xUnit действительно) и Mockito (любой макет действительно) , прежде чем вы начнете думать, что структура DI должна взять на себя вашу жизнь.

Вы можете делать то, что вам нравится, но для серьезной работы я предпочитаю хорошо заполненный ящик для инструментов швейцарскому армейскому ножу. Желание это было легче сделать эти строки, но некоторые из них работали, чтобы размыть их. Ничего плохого в этом, но это может сделать этот выбор сложным.

ответил Winston Ewert 16 Mayam16 2016, 07:25:34
2

Создание классов и назначение их зависимостей является частью процесса моделирования, забавных частей. Именно по этой причине большинство программистов пользуются программированием.

Решая, какая реализация будет использоваться и как построены классы, это вещь, которая должна быть каким-то образом реализована и является частью конфигурации приложения.

Вручную писать фабрики - утомительная работа. DI упрощают автоматическое разрешение зависимостей, которые могут быть разрешены и требуют конфигурации для тех, которые не могут быть.

Использование современных IDE позволяет вам перемещаться по методам и их обычаям. Наличие вручную написанных фабрик неплохое, потому что вы можете просто выделить конструктор класса, показать его использование, и он покажет вам все места, где и как создается конкретный класс.

Но даже с каркасом DI вы можете иметь центральное место, например конфигурацию построения графического объекта (OGCC с этого момента), а если класс зависит от двусмысленных зависимостей, вы можете просто взглянуть на OGCC и посмотреть, как определенный класс строится прямо там.

Вы можете возразить, что вы лично считаете, что возможность увидеть использование конкретного конструктора - отличный плюс. Я бы сказал, что то, что лучше для вас, не только субъективно, но в основном связано с личным опытом.

Если вы всегда работали над проектами, основанными на инфраструктурах DI, вы бы действительно знали только это, и когда вы хотели видеть конфигурацию класса, вы всегда будете смотреть в OGCC и даже не попытаетесь увидеть, как конструкторы используются, потому что вы знаете, что зависимости все подключены автоматически в любом случае.

Естественно, рамки DI не могут использоваться для всего, и время от времени вам придется писать фабричный метод или два. Очень распространенным случаем является построение зависимости во время итерации над коллекцией, где каждая итерация предоставляет другой флаг, который должен производить другую реализацию обычного интерфейса.

В конце концов, скорее всего, все придет к вашим предпочтениям и тем, что вы готовы пожертвовать (или время написания фабрик или прозрачность).


Личный опыт (предупреждение: субъективное)

Говоря как разработчик PHP, хотя мне нравится идея структур DI, я использовал их только один раз. Именно тогда команда, с которой я работал, должна была быстро развернуть приложение, и мы не могли потерять время, называя фабрики. Поэтому мы просто подобрали структуру DI, настроили ее, и она работала, как-то .

Для большинства проектов мне нравится, чтобы фабрики были написаны вручную, потому что мне не нравится черная магия, происходящая внутри каркасов DI. Я был ответственным за моделирование класса и его зависимостей. Я был единственным, кто решил, почему дизайн выглядит так, как он. Таким образом, я буду тем, кто правильно построит класс (даже если класс принимает жесткие зависимости, такие как конкретные классы, а не интерфейсы).

ответил Andy 14 Maypm16 2016, 23:40:41
1

Как вы уже заметили: в зависимости от языка, который вы используете, есть разные точки зрения, diffenrent берет на себя как справиться с подобными проблемами.

Что касается инъекции зависимостей, это сводится к следующему: инъекция зависимостей, как говорит этот термин, не более чем помещает зависимости, которые один объект нуждается в , в , этот объект - контрастирует другим способом: позволяя сам объект инсталирует экземпляры объектов, от которых он зависит. Вы отделяете создание объектов и потребление объектов для выигрыша большей гибкости.

Если ваш проект хорошо проложен, у вас обычно есть несколько классов со многими зависимостями, поэтому проводка зависимостей - либо вручную, либо каркасом - должна быть относительно простой, а количество шаблонов для написания тестов должно быть легко управляемый.

Тем не менее, нет необходимости в DI-каркасе.

Но почему вы хотите использовать фреймворк?

I) Избегайте кода шаблона

Если ваш проект получает размер, где вы снова и снова чувствуете боль от написания фабрик (и уставок), вы должны использовать DI-framework

II) Декларативный подход к программированию

Когда Java когда-то выполнял программирование с помощью XML , теперь он: разбрызгивает fairydust с аннотациями и происходит magic .

Но серьезно: я вижу ясный потенциал роста . Вы четко сообщаете намерение говорить о том, что нужно, а не где его искать и как его строить.


TL; др

Фреймворки DI не делают вашу кодовую базу магически лучше, но это помогает сделать красивый код, выглядящий действительно crisp . Используйте его, когда вы чувствуете, что вам это нужно. В определенный момент вашего проекта это сэкономит ваше время и предотвратит тошноту.

ответил Thomas Junk 16 J000000Sunday17 2017, 13:14:26
1

Лично я не использую DI-контейнеры и не люблю их. У меня есть еще несколько причин для этого.

Обычно это статическая зависимость. Таким образом, это всего лишь локатор услуг со всеми его недостатками. Затем, из-за природы статических зависимостей, они скрыты. Вам не нужно иметь дело с ними, они как-то уже там, и это опасно, потому что вы перестаете контролировать их.

Он нарушает принципы ООП , например, сцепление и метафорическая метафора Лего-кирпича Дэвида Уэста . /р>

Таким образом, построим весь объект как можно ближе к точке входа программы это путь.

ответил 26 +03002017-10-26T00:42:38+03:00312017bEurope/MoscowThu, 26 Oct 2017 00:42:38 +0300 2017, 00:42:38
0

Да. Вероятно, вам следует прочитать книгу Марка Семанна под названием «Инъекция зависимостей». Он описывает некоторые хорошие практики. Основываясь на некоторых из того, что вы сказали, вы можете воспользоваться. Вы должны стремиться иметь один корень композиции или один корень композиции на единицу работы (например, веб-запрос). Мне нравится, как он думает, что любой объект, который вы создаете, считается зависимым (как и любой параметр для метода /конструктора), поэтому вам действительно нужно быть осторожным, где и как вы создаете объекты. Структура поможет вам сохранить эти концепции понятными. Если вы прочитаете книгу Марка, вы найдете больше, чем просто ответ на свой вопрос.

ответил keith 14 Maypm16 2016, 23:58:07
0

Да, когда я работаю на Java, я бы рекомендовал структуру DI. Для этого есть несколько причин:

  • В Java есть несколько чрезвычайно хороших пакетов DI, которые предлагают автоматическую инъекцию зависимостей, а также обычно поставляются с дополнительными возможностями, которые сложнее писать вручную, чем простой DI (например, зависимые от области действия области, которые позволяют автоматическое соединение между областями путем генерации кода для просмотра какой объем должен использоваться d найти правильную версию зависимостей для этой области - так, например, объекты с областью приложения могут ссылаться на области с запросом).

  • аннотации java чрезвычайно полезны и обеспечивают отличный способ настройки зависимостей

  • Конструкция объекта java слишком многословна по сравнению с тем, что вы использовали в python; использование структуры здесь экономит больше работы, чем на динамическом языке.

  • java DI frameworks может делать полезные вещи, такие как автоматическое создание прокси и декораторов, которые больше работают на Java, чем динамический язык.

ответил Jules 15 Mayam16 2016, 11:04:55
0

Если ваш проект достаточно мал, и у вас нет большого опыта работы с DI-Framework, я бы рекомендовал не использовать фреймворк и сделать вручную.

Причина: я когда-то работал над проектом, который использовал две библиотеки, которые имели прямые зависимости к различным фреймворкам. они оба имеют каркасный специфический код, например, di-give-me-a-instance-of-XYZ. Насколько я знаю, вы можете иметь только одну активную реализацию di-framework за раз.

с таким кодом вы можете принести больше вреда, чем пользы.

Если у вас больше опыта, вы, вероятно, можете отвлечь ди-каркас от интерфейса (фабрики или servicelocator), так что эта проблема больше не будет существовать, а рамки di будут приносить больше пользы от этого вреда.

ответил k3b 8 MarpmWed, 08 Mar 2017 13:30:47 +03002017-03-08T13:30:47+03:0001 2017, 13:30:47

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

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132