По поводу вашего вопроса о наличии только одной реализации интерфейса. Когда вы используете IoC, по-прежнему полезно использовать интерфейс. Будет намного проще создавать настоящие модульные тесты (это не t зависит от реализации интерфейса, чтобы он работал правильно), используя макеты для этих интерфейсов. Суть использования IoC - это упрощение тестирования кода. Итак, не используйте IoC, если вы не хотите тестировать или у вас уже есть лучший план тестирования без него.
IMHO, Повышение сложности DI и IoC оплачивается за счет того, что тестирование становится проще. и менее связанный код. Проще изолировать проблемы и внести изменения в будущем. Вы также можете лучше контролировать его поведение.
Я вижу, когда не следует использовать контейнер IoC (поскольку это приводит к накладным расходам на настройку). Это может произойти в небольших проектах, где вы можете сделать это вручную, а не использовать контейнер. Но я не вижу больших потерь от использования DI, если только вы не планируете тестировать свой код ...
t используйте IoC, если вы не хотите тестировать или у вас уже есть лучший план тестирования без него.IMHO, Увеличение сложности DI и IoC оплачивается за счет более простого тестирования и менее связанного кода . Проще изолировать проблемы и внести изменения в будущем. Вы также можете лучше контролировать его поведение.
Я вижу, когда не следует использовать контейнер IoC (поскольку это приводит к накладным расходам на настройку). Это может произойти в небольших проектах, где вы можете сделать это вручную, а не использовать контейнер. Но я не вижу больших потерь от использования DI, если только вы не планируете тестировать свой код ...
t используйте IoC, если вы не хотите тестировать или у вас уже есть лучший план тестирования без него.IMHO, Увеличение сложности DI и IoC оплачивается за счет более простого тестирования и менее связанного кода . Проще изолировать проблемы и внести изменения в будущем. Вы также можете лучше контролировать его поведение.
Я вижу, когда не следует использовать контейнер IoC (поскольку это приводит к накладным расходам на настройку). Это может произойти в небольших проектах, где вы можете сделать это вручную, вместо использования контейнера. Но я не вижу больших потерь от использования DI, если только вы не планируете тестировать свой код ...
s легче изолировать проблемы и внести изменения в будущем. Вы также можете лучше контролировать его поведение.Я вижу, когда не следует использовать контейнер IoC (поскольку это приводит к накладным расходам на настройку). Это может произойти в небольших проектах, где вы можете сделать это вручную, вместо использования контейнера. Но я не вижу больших потерь от использования DI, если только вы не планируете тестировать свой код ...
s легче изолировать проблемы и внести изменения в будущем. Вы также можете лучше контролировать его поведение.Я вижу, когда не следует использовать контейнер IoC (поскольку это приводит к накладным расходам на настройку). Это может произойти в небольших проектах, где вы можете сделать это вручную, вместо использования контейнера. Но я не вижу больших потерь от использования DI, если только вы не планируете тестировать свой код ...
Использование контейнера IoC или без него - это не решение, которое следует принимать на уровне отдельных классов - в любом проекте у вас будут типы, которые создаются и не создаются контейнером.
Компромисс сложности заключается в следующем:
Если вы когда-либо сталкивались с феноменом того, что даже хорошо спроектированная и поддерживаемая кодовая база становится неуправляемой из-за размера, вы столкнулись с проблемой, которую решают контейнеры IoC.
Из Castle Project :
Почему бы мне не использовать его?
Вы не должны использовать инверсию Контейнер управления, если вы не знакомы с концепциями, и если вы не осознают проблемы, которые они пытаются решить.
Также, в зависимости от размера и сложность проекта, IoC контейнер может быть излишним. Предпочитаю используйте его в средних и крупных проектах.
Жалобы на 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 () и (иногда) даже содержимое списков для итерации.
Да, XML-файл сделал ваше программное обеспечение более настраиваемым! Правильно? Вы можете изменить, что что-то делается в вашем списке, просто изменив простой текстовый файл!
По иронии судьбы, ваш исходный код теперь длиннее и его сложнее понять, это зависит от всех видов новых, возможно, содержат ошибки, библиотеки (включая IocContainer и XML-анализатор), и вы фактически усложнили обслуживание: XML-код сложнее для понимания и редактирования, чем исходный простой цикл исходного кода (независимо от того, что язык, на котором написан цикл). У вас также меньше контроля над тем, как именно вы хотите выполнять итерацию (отсортированные или несортированные? В глубину или в ширину?), Поскольку IocContainer снимает с вас эту ответственность.
Для таких вещей, как плагины, это может иметь смысл использовать IoC, поскольку логично , чтобы основное приложение контролировало процесс выполнения, и просто просить плагин о помощи тут и там. Это называется «обеспечение ловушек» и существует гораздо дольше, чем терминология IoC.
Для таких вещей, как модульные тесты (которые я обычно видел, как это происходит), IoC обычно оказывается бесполезным, потому что ваш тесты должны иметь возможность моделировать самые разные странные ситуации, и IoC постоянно мешает этому.
Фундаментальное предположение IoC состоит в том, что загрузка данных и их выполнение в цикле каким-то образом сложны и должны быть исключены; это предположение просто неверно, потому что в любом случае это никогда не было больше пары строк (или вы могли переместить его в отдельную функцию), и даже если он сохранил код, это снижает вашу гибкость.
Я бы сказал, что простой ответ использовать IoC только для объектов, которые вы хотите тестировать.
Если это кажется легкомысленным, извините, это из-за разочарования в коде, написанном с помощью буквально НИКАКОГО внимания уделяется модульному тестированию. Я действительно не понимаю, почему возникает дополнительная сложность - если мне нужно точно знать фактический тип объекта, я всегда могу распечатать класс во время выполнения.
IoC / DI - это не технологии, это парадигмы. Ваш вопрос похож на вопрос: «Когда мне не следует использовать объектно-ориентированное программирование?» Это решение больше, чем отдельные единицы вашей кодовой базы.
Чтобы ответить на ваш конкретный вопрос, если у вас мало классов, в которых вы можете разумно построить графы объектов вручную, и вы не повторяете те же экземпляры графов объектов несколько раз вам может не понадобиться контейнер IoC.
Inversion of Control = Marriage
IOC Container = Wife
Marriage is the definition of a known pattern - Wife is the implementation of that pattern ;-)
Bernard.