Инъекция зависимости: что плохого в старомодном рефакторинге? - PullRequest
4 голосов
/ 27 марта 2010

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

Но почему бы просто не выполнить рефакторинг, если вы хотите использовать другой класс реализации? Другие языки, такие как Python и Ruby, работают нормально. Почему не Java?

Ответы [ 3 ]

13 голосов
/ 27 марта 2010

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

Следует также отметить, что внедрение зависимости обычно используется в качестве решения для анти-паттерна Singleton; это позволяет иметь одноэлементный объект, который может быть легко смоделирован во время тестирования. И, если позже окажется, что синглтонное допущение действительно неверно, этот синглтон можно заменить различными реализациями.

Некоторые ресурсы, которые могут оказаться полезными для лучшего понимания темы:

0 голосов
/ 14 января 2011

Не совсем. Проблема здесь в том, что когда вы пишете фрагмент кода вроде:

Runnable r = new MyFooRunnable();

вы решаете, что вам необходим Runnable - это MyFooRunnable (а не MyBarRunnable или третий). Иногда вам может понадобиться отложить это решение со времени компиляции до времени развертывания , чтобы развертыватель мог решить, как отдельные модули, из которых состоит ваше приложение, должны быть склеены.

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

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

Таким образом, Dependency Injection, используемое в широком смысле, позволяет вам писать модули, которые «хорошо сочетаются» друг с другом, не зная друг друга во время компиляции. Это очень похоже на концепцию jar-файла, но на его взросление ушло больше времени.

0 голосов
/ 27 марта 2010

То есть вы говорите, что у Python и Ruby не может быть внедрения зависимостей? Или Java не может нормально работать без DI?

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

...