Я понимаю преимущества самой инъекции зависимостей. Возьмем, к примеру, Spring. Я также понимаю преимущества других функций Spring, таких как АОП, различных помощников и т. Д. Мне просто интересно, каковы преимущества конфигурации XML, такие как:
<bean id="Mary" class="foo.bar.Female">
<property name="age" value="23"/>
</bean>
<bean id="John" class="foo.bar.Male">
<property name="girlfriend" ref="Mary"/>
</bean>
по сравнению с обычным старым Java-кодом, например:
Female mary = new Female();
mary.setAge(23);
Male john = new Male();
john.setGirlfriend(mary);
который легче отлаживать, проверять во время компиляции и понять любой, кто знает только java. Итак, какова основная цель инфраструктуры внедрения зависимостей? (или фрагмент кода, показывающий его преимущества.)
ОБНОВЛЕНИЕ:
в случае
IService myService;// ...
public void doSomething() {
myService.fetchData();
}
Как структура IoC может угадать, какую реализацию myService я хочу внедрить, если их больше одной? Если существует только одна реализация данного интерфейса, и я позволяю контейнеру IoC автоматически решать его использовать, он будет сломан после появления второй реализации. И если есть намеренно только одна возможная реализация интерфейса, вам не нужно вводить ее.
Было бы действительно интересно увидеть небольшую конфигурацию для IoC, которая показывает его преимущества. Я уже давно использую Spring и не могу привести такой пример. И я могу показать отдельные строки, демонстрирующие преимущества hibernate, dwr и других фреймворков, которые я использую.
ОБНОВЛЕНИЕ 2:
я понимаю, что конфигурацию IoC можно изменить без перекомпиляции. Неужели это такая хорошая идея? Я могу понять, когда кто-то хочет изменить учетные данные БД без перекомпиляции - он может быть не разработчиком. Как часто в вашей практике кто-то другой, кроме разработчика, меняет конфигурацию IoC? Я думаю, что разработчикам не нужно перекомпилировать этот конкретный класс вместо изменения конфигурации. А не разработчику вы, вероятно, захотите облегчить его жизнь и предоставить более простой файл конфигурации.
ОБНОВЛЕНИЕ 3:
Внешняя конфигурация отображения между интерфейсами и их конкретными реализациями
Что же такого хорошего в том, чтобы сделать его внешним? Вы не делаете весь свой код внешним, хотя вы определенно можете - просто поместите его в файл ClassName.java.txt, прочтите и скомпилируйте вручную на лету - вау, вы избежали перекомпиляции. Почему следует избегать компиляции ?!
Вы экономите время на кодирование, потому что вы предоставляете сопоставления декларативно, а не в процедурном коде.
Понимаю, что иногда декларативный подход экономит время. Например, я объявляю только один раз сопоставление между свойством компонента и столбцом БД, и спящий режим использует это сопоставление при загрузке, сохранении, построении SQL на основе HSQL и т. Д. Здесь работает декларативный подход. В случае Spring (в моем примере) объявление имело больше строк и такую же выразительность, как и соответствующий код. Если есть пример, когда такое объявление короче кода - хотелось бы его увидеть.
Принцип инверсии управления позволяет упростить модульное тестирование, поскольку вы можете заменить реальные реализации поддельными (например, заменить базу данных SQL базой данных в памяти)
Я понимаю преимущества инверсии управления (я предпочитаю называть обсуждаемый здесь шаблон проектирования как внедрение зависимостей, потому что IoC является более общим - существует много видов управления, и мы инвертируем только один из них - контроль инициализации). Я спрашивал, зачем кому-то для этого нужно что-то, кроме языка программирования. Я определенно могу заменить настоящие реализации на поддельные с помощью кода. И этот код будет выражать то же самое, что и конфигурация - он просто инициализирует поля поддельными значениями.
mary = new FakeFemale();
Я понимаю преимущества DI. Я не понимаю, какие преимущества добавляет внешняя конфигурация XML по сравнению с конфигурационным кодом, который делает то же самое. Не думаю, что следует избегать компиляции - я компилирую каждый день и все еще жив. Я считаю, что конфигурация DI - плохой пример декларативного подхода. Объявление может быть полезно, если объявлено один раз и используется много раз разными способами - например, hibernate cfg, где сопоставление между свойством bean-компонента и столбцом DB используется для сохранения, загрузки, построения поисковых запросов и т. Д. Конфигурация Spring DI может быть легко преобразована в настройка кода, как в начале этого вопроса, не так ли? И используется он только для инициализации bean-компонентов, не так ли? Значит, декларативный подход здесь ничего не добавляет?
Когда я объявляю отображение гибернации, я просто даю спящему режиму некоторую информацию, и он работает на основе этого - я не говорю ему, что делать. В случае Spring мое объявление сообщает Spring, что именно делать - так зачем объявлять это, почему бы просто не сделать это?
ПОСЛЕДНЕЕ ОБНОВЛЕНИЕ:
Ребята, многие ответы говорят мне о внедрении зависимостей, что я ЗНАЮ ХОРОШО. Вопрос заключается в назначении конфигурации DI вместо инициализации кода - я склонен думать, что код инициализации короче и понятнее. Единственный ответ, который я получил на свой вопрос, заключается в том, что он позволяет избежать перекомпиляции при изменении конфигурации. Думаю, мне стоит задать еще один вопрос, потому что для меня это большой секрет, почему в этом случае следует избегать компиляции.