До сих пор нет присяжных на предмет использования DI в контексте вашего вопроса. Вы спросили, является ли тестирование одним из оправданий для внедрения DI, и я собираюсь немного походить на собеседника, отвечающего на это, даже если мой инстинктивный ответ - нет.
Если я отвечаю «да», я думаю о тестировании систем, когда у вас нет ничего, что вы можете легко протестировать напрямую. В физическом мире нет ничего необычного в том, чтобы включать порты, туннели доступа, бобышки и т. Д., Чтобы обеспечить простые и прямые средства проверки состояния систем, машин и т. Д. Это кажется разумным в большинстве случаев. Например, нефтепровод имеет смотровые люки, позволяющие впрыскивать оборудование в систему для проведения испытаний и ремонта. Они специально построены и не предоставляют никакой другой функции. Однако реальный вопрос в том, подходит ли эта парадигма для разработки программного обеспечения. Часть меня хотела бы сказать «да», но, похоже, ответ будет стоить и оставит нас в этой прекрасной серой области балансирования выгод и затрат.
Аргумент "нет" действительно сводится к причинам и целям проектирования программных систем. DI - это прекрасный шаблон для продвижения слабой связи кода, чему нас учат в наших классах ООП, это очень важная и мощная концепция проектирования для улучшения удобства сопровождения кода. Проблема в том, что, как и все инструменты, им можно злоупотреблять. Я собираюсь не согласиться с ответом Роба, приведенным выше, отчасти потому, что преимущества DI связаны не с тестированием, а с продвижением слабосвязанной архитектуры. И я бы поспорил, что обращение к проектированию систем, основанных исключительно на возможности их тестирования, предполагает в таких случаях, что либо архитектура имеет недостатки, либо контрольные примеры настроены неправильно, и, возможно, даже оба.
Хорошо продуманная системная архитектура в большинстве случаев по своей природе проста для тестирования, а внедрение платформ для моделирования за последние десять лет делает тестирование еще проще. Опыт научил меня тому, что любая система, которую я испытывал с трудом, имела какой-то аспект слишком тесно связанный. Иногда (реже) это оказывалось необходимым, но в большинстве случаев этого не было, и обычно, когда казалось бы, что простая система казалась слишком сложной для тестирования, это происходило из-за того, что парадигма тестирования была ошибочной. Я видел, как DI использовался в качестве средства, позволяющего обойти проектирование системы, чтобы можно было протестировать систему, и риски, безусловно, перевесили предполагаемые выгоды, при этом архитектура системы была эффективно повреждена. Под этим я подразумеваю «задние двери» в коде, приводящие к проблемам с безопасностью, коду, раздутому с поведением, специфичным для тестов, которое никогда не используется во время выполнения, и спагеттификации исходного кода, так что вам понадобится пара плат Sherpa и Ouija Board, чтобы выяснить, какие путь был! Все это в отгруженном производственном коде. Результирующие затраты на обслуживание, кривую обучения и т. Д. Могут быть астрономическими, и для небольших компаний такие потери могут оказаться разрушительными в долгосрочной перспективе.
ИМХО, я не верю, что DI следует когда-либо использовать как средство для простого улучшения тестируемости кода. Если DI - ваш единственный вариант для тестирования, то дизайн, как правило, нуждается в рефакторинге. С другой стороны, реализация DI путем разработки, где она может использоваться как часть кода времени выполнения, может дать явные преимущества, но не должна использоваться неправильно, поскольку это также может привести к неправильному использованию классов и не должно быть чрезмерным используется просто потому, что это кажется классным и простым, поскольку в таких случаях это может усложнить разработку кода.
: -)