Подтвердить что ты не робот

Когда не использовать IoC и DI?

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

Это хороший поток: Что такое инверсия управления?. Если вы посмотрите дальше, появится сообщение о проверке орфографии и другое сообщение о том, что IoC, вероятно, не очень хорошо там используется, если это всего лишь один инструмент проверки орфографии. Как правило, если IoC не будет использоваться, у меня будет только один конкретный класс для интерфейса? Смысл, у меня есть IMyClass. И тогда есть только конкретный MyClassA, который реализует IMyClass. Почему я хочу там IoC?

Если у меня были MyClassA, MyClassB и MyClassC, каждый из которых реализует IMyClass, это, вероятно, хорошие кандидаты для IoC правильно?

Из того же потока кто-нибудь знает, что означает этот пост:

  • Инверсия контроля = брак
  • Контейнер IOC = Жена
4b9b3361

Ответ 1

О вашем вопросе о наличии только одной реализации интерфейса. Когда вы используете IoC, все же полезно использовать интерфейс. Намного проще создавать реальные модульные тесты (которые не зависят от реализации интерфейса для правильной работы) с использованием mocks для этих интерфейсов. Ядро использования IoC упрощает тестирование кода. Таким образом, не используйте IoC, если вы не хотите тестировать или у вас уже есть лучший план тестирования без него.

ИМХО, Увеличение и увеличение уровня IoC по сложности достигается за счет более легкого тестирования и менее связанного кода. Легче изолировать проблемы и вносить будущие изменения. Вы также можете лучше контролировать свое поведение.

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

Ответ 2

Инверсия контроля = брак

IOC Container = Wife

Брак - это определение известного шаблона - Жена - это реализация этого шаблона; -)

Bernard.

Ответ 3

Использование контейнера IoC или нет - это не решение сделать на уровне отдельных классов - в любом проекте у вас будут типы, которые созданы и не созданы контейнером.

Компромисс сложности заключается в следующем:

  • Для небольшого количества компонентов контейнер IoC добавляет некоторые служебные данные
  • По мере увеличения количества компонентов в приложении:
    • Без контейнера IoC добавление новых компонентов или рефакторинг становится все труднее.
    • С контейнером IoC добавление новых компонентов или рефакторинг остается неизменным: вам всегда нужно беспокоиться о непосредственных зависимостях компонента, который вы добавляете или меняете.

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

Ответ 4

От Проект Замка:

Почему бы мне не использовать его?

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

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

Ответ 5

Жалобы на IoC легко понять: IoC превращает что-то просто в нечто сложное. Скажем, вы хотели что-то сделать для каждого элемента списка (в псевдокоде):

for each i in list:
    do_something(i)

IoC, по сути, переносит ответственность за итерацию цикла на кого-то другого. Таким образом, мы получаем нечто большее:

ioc = new IocContainer()
ioc.register_callback(do_something)
ioc.go()

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

Затем, в своей самой причудливой форме, IocContainer может быть инициализирован статически или статической функцией Main() или где-то еще скрытым, а функции register_callback() автоматически вызываются на основе другого кода, который итерации через XML файл который перечисляет все ваши функции do_something() и (иногда) даже содержимое списков для итерации.

Yay, файл XML сделал ваше программное обеспечение более настраиваемым! Правильно? Вы можете изменить, какие дела делаются в вашем списке, просто изменив простой текстовый файл!

Кроме того, по иронии судьбы, ваш исходный код теперь длиннее и сложнее понять, он зависит от всех видов новых, возможно, багги, библиотек (включая IocContainer и XML-парсер), и вам на самом деле было сложнее поддерживать: XML-код сложнее понять и редактировать, чем исходный простой цикл исходного кода (независимо от того, на каком языке написан цикл). У вас также меньше контроля над тем, как вы хотите выполнять итерацию (отсортированную или несортированную? Глубину-сначала или ширину?), Поскольку IocContainer отнимает эту ответственность от вас.

Для таких вещей, как плагины, может иметь смысл использовать IoC, поскольку логично для основного приложения контролировать процесс выполнения и просто запрашивать плагин для справки здесь и там. Это называется "предоставление перехватчиков" и существует гораздо дольше, чем терминология IoC.

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

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

Ответ 6

IoC/DI не являются технологиями, они являются парадигмами. Ваш вопрос сродни запросу "Когда я не должен использовать объектно-ориентированное программирование?" Это решение, которое больше, чем отдельные единицы вашей кодовой базы.

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

Ответ 7

Думаю, я бы сказал, что простой ответ использует только IoC на объектах, которые вы хотите unit test.

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

Ответ 8

В этой статье рассматривается ваш вопрос "где конкретно вы не должны использовать эти шаблоны?" и дает подробные примеры, касающиеся вашего комментария, что "два шаблона ([IoC и DI]) могут сделать код более сложным":

http://java.dzone.com/articles/beyond-injection-concerns-ioc.

Подводя итог двум пунктам этой статьи:

  • Вам не следует использовать IoC/DI, где важна инкапсуляция.
  • Вам не следует использовать IoC/DI, где вы не можете продемонстрировать конкретные примеры того, как сложность, добавленная посредством использования IoC/DI, взвешивается преимуществами использования IoC/DI.