Каковы преимущества инъекционных контейнеров для зависимости?

94

Я понимаю преимущества самой инъекции зависимостей. Возьмем, например, Spring. Я также понимаю преимущества других Spring функций, таких как AOP, помощников разных типов и т.д. Мне просто интересно, каковы преимущества конфигурации 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. Итак, какова основная цель рамки инъекций зависимостей? (или фрагмент кода, который показывает его преимущества.)


UPDATE:
В случае

IService myService;// ...
public void doSomething() {  
  myService.fetchData();
}

Как может структура IoC угадать, какую реализацию myService я хочу ввести, если ее несколько? Если есть только одна реализация данного интерфейса, и я позволяю контейнеру IoC автоматически решать использовать его, он будет прерван после появления второй реализации. И если есть намеренно только одна возможная реализация интерфейса, тогда вам не нужно вводить его.

Было бы очень интересно увидеть небольшую часть конфигурации для IoC, которая показывает, что это выгодно. Я использовал Spring какое-то время, и я не могу представить такой пример. И я могу показать отдельные строки, которые демонстрируют преимущества спящего режима, dwr и других фреймворков, которые я использую.


ОБНОВЛЕНИЕ 2:
Я понимаю, что конфигурация IoC может быть изменена без повторной компиляции. Это действительно такая хорошая идея? Я могу понять, когда кто-то хочет изменить учетные данные БД без перекомпиляции - он может быть не разработчиком. В вашей практике, как часто кто-то другой, кроме разработчика, меняет конфигурацию IoC? Я думаю, что для разработчиков нет усилий перекомпилировать этот конкретный класс вместо изменения конфигурации. А для не-разработчиков вы, вероятно, захотите сделать свою жизнь проще и предоставить более простой конфигурационный файл.


ОБНОВЛЕНИЕ 3:

Внешняя конфигурация отображения между интерфейсами и их конкретными реализациями

Что хорошего в том, чтобы сделать его extenal? Вы не делаете весь свой код внешним, в то время как вы определенно можете - просто поместите его в файл ClassName.java.txt, прочитайте и скомпилируйте вручную на лету - ничего себе, вы избежали перекомпиляции. Почему следует избегать компиляции?!

Вы сохраняете время кодирования, потому что вы предоставляете сопоставления декларативно, а не в процедурный код

Я понимаю, что иногда декларативный подход экономит время. Например, я объявляю только один раз, когда сопоставление между свойством bean и столбцом базы данных, а спящий режим использует это сопоставление при загрузке, сохранении, построении SQL на основе HSQL и т.д. Здесь работает декларативный подход. В случае Spring (в моем примере) объявление имеет больше строк и имеет ту же выразительность, что и соответствующий код. Если есть пример, когда такое объявление короче кода - я бы хотел его увидеть.

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

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

mary = new FakeFemale();

Я понимаю преимущества DI. Я не понимаю, какие преимущества добавляются внешней конфигурацией XML по сравнению с настройкой кода, который делает то же самое. Я не думаю, что компиляции следует избегать - я собираю каждый день, и я все еще жив. Я думаю, что конфигурация DI является плохим примером декларативного подхода. Объявление может быть полезно, если объявлено один раз И используется много раз по-разному - например, hibernate cfg, где сопоставление между свойством bean и столбцом базы данных используется для сохранения, загрузки, построения поисковых запросов и т.д. Spring Конфигурация DI может можно легко перевести на код настройки, как в начале этого вопроса, не так ли? И он используется только для инициализации bean, не так ли? Что означает, что декларативный подход ничего здесь не добавляет, не так ли?

Когда я объявляю отображение hibernate, я просто предоставляю hibernate некоторую информацию, и она работает на основе этого - я не говорю, что делать. В случае spring моя декларация сообщает Spring точно, что делать, поэтому зачем объявлять ее, почему бы просто не сделать это?


ПОСЛЕДНЕЕ ОБНОВЛЕНИЕ:
Ребята, много ответов рассказывают мне об инъекции зависимостей, которые я ЗНАЮ ХОРОШО. Вопрос заключается в цели конфигурации DI вместо инициализации кода. Я склонен думать, что код инициализации короче и яснее. Единственный ответ, который я получил до сих пор на мой вопрос, заключается в том, что он избегает перекомпиляции при изменении конфигурации. Я предполагаю, что должен опубликовать еще один вопрос, потому что это большой секрет для меня, почему в этом случае следует избегать компиляции.

  • 21
    Наконец кто-то набрался смелости задать этот вопрос. Почему на самом деле вы хотели бы избежать перекомпиляции, если ваша реализация меняется за счет потери (или, по крайней мере, снижения качества) поддержки инструмента / IDE?
  • 3
    Кажется, название не совсем правильное. Автор сказал, что с контейнерами IOC все в порядке, но, похоже, возникают проблемы с использованием XML-конфигурации вместо настройки с помощью кода (и тоже достаточно справедливо). Я бы предложил, возможно, «Каковы преимущества настройки контейнеров IOC с помощью XML или других не кодовых подходов?»
Показать ещё 3 комментария
Теги:
spring
dependency-injection

16 ответов

36
Лучший ответ

Для меня одной из основных причин использования IoC (и использования внешней конфигурации) является две области:

  • Тестирование
  • Техническое обслуживание

Тестирование

Если вы разделите свое тестирование на 3 сценария (что довольно нормально в крупномасштабной разработке):

  • Тестирование модулей
  • Тестирование интеграции
  • Проверка черного ящика

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

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

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

Продукция

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

Резюме

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

  • Приложение распространяется на несколько сайтов/клиентов, где среда будет отличаться.
  • Ограниченный контроль разработки/ввод в производственную среду и настройку.
  • Сценарии тестирования.

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

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

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

13

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

Язык должен обеспечивать хорошую поддержку как обычных объектно-ориентированных методов программирования, так и поддержки интерфейсов объектов и отражения объектов (например, Java и С#). Хотя вы можете создавать программы с использованием шаблонов DI в системах С++, отсутствие поддержки рефлексии в правильном языке не позволяет ему поддерживать серверы приложений и другие платформы ДИ и, следовательно, ограничивает выразительность шаблонов DI.

Сильные стороны системы, построенной с использованием шаблонов DI:

  • Код DI намного проще использовать, поскольку функциональность "зависит" экстраполируется на хорошо определенные интерфейсы, позволяя отдельным объектам, конфигурация которых обрабатывается подходящей платформой приложений, которая будет подключаться к другим объектам по желанию.
  • Код DI намного проще проверить. Функциональность, выражаемая объектом, может быть протестирована в "черном ящике", построив объекты "mock", реализующие интерфейсы, ожидаемые вашей логикой приложения.
  • Код DI более гибкий. Это врожденно слабо связанный код - до крайности. Это позволяет программисту выбирать и выбирать, как объекты подключаются, основываясь исключительно на их требуемых интерфейсах на одном конце, а их выраженные интерфейсы - на другом.
  • Внешняя (Xml) конфигурация объектов DI означает, что другие могут настроить ваш код в непредвиденных направлениях.
  • Внешняя конфигурация также является разделом шаблона озабоченности тем, что все проблемы инициализации объекта и управления взаимозависимостью объекта могут обрабатываться сервером приложений.
  • Обратите внимание, что внешняя конфигурация не требуется для использования шаблона DI, для простых межсоединений небольшой объект-строитель часто является адекватным. Между ними есть гибкость. Объект-строитель не такой гибкий, как внешний вид файла конфигурации. Разработчик системы DI должен взвесить преимущества гибкости по сравнению с удобством, заботясь о том, чтобы мелкомасштабный контроль мелкой зернистости над конструкцией объекта, выраженный в файле конфигурации, может увеличивать путаницу и затраты на обслуживание по линии.

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

Пример, представленный в вопросе, затрагивает только поверхность выразительной мощности, которую может предоставить библиотека с факторизованным объектом. С некоторой практикой и большим количеством самодисциплины большинство практикующих DI находят, что они могут создавать системы, которые имеют 100% -ный охват тестирования кода приложения. Этот один только один является экстраординарным. Это не 100% -ный охват тестирования небольшого приложения нескольких сотен строк кода, но 100% -ный охват тестирования приложений, включающий сотни тысяч строк кода. Я теряю способность описывать любой другой шаблон проектирования, который обеспечивает этот уровень проверки.

Вы правы в том, что приложение из простых 10-ти строк кода легче понять, чем несколько объектов, а также ряд файлов конфигурации XML. Однако, как и в случае с наиболее мощными шаблонами проектирования, выигрыши обнаруживаются при продолжении добавления новых функций в систему.

Короче говоря, широкомасштабные приложения на основе DI легче отлаживать и легче понять. Хотя конфигурация Xml не проверяется временем компиляции, все приложения, которые этот автор знает, предоставят разработчику сообщения об ошибках, если они попытаются вставить объект, имеющий несовместимый интерфейс, в другой объект. И большинство из них обеспечивают функцию проверки, которая охватывает все известные конфигурации объектов. Это легко и быстро делается путем проверки того, что объект A, который должен быть инъецирован, реализует интерфейс, требуемый объектом B для всех сконфигурированных инъекций объектов.

  • 4
    понять преимущества DI. Я не понимаю, какие преимущества добавляет внешняя конфигурация XML по сравнению с настройкой кода, который делает то же самое. Упомянутые вами преимущества обеспечиваются DI design pattern. Вопрос был о преимуществах конфигурации DI по сравнению с простым кодом инициализации.
  • 0
    > Внешняя конфигурация также является разделением ... Разделение конфигурации является сердцем DI, и это хорошо. И это может быть сделано с помощью кода инициализации. Что добавляет cfg по сравнению с инициализацией кода? Мне кажется, что каждая строка cfg имеет соответствующую строку кода инициализации.
7

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

Они упрощают код во много раз, но у них также есть накладные расходы по сложности, что затрудняет отслеживание проблем (я видел такие проблемы из первых рук, и прямая Java, с которой мне было бы гораздо удобнее общаться).

Я предполагаю, что это немного зависит от стиля, и с чем вам комфортно... вы любите летать по собственному решению и иметь возможность знать его наизнанку или использовать существующие решения, которые могут оказаться трудными, когда Конфигурация не только правильная? Все это компромисс.

Однако конфигурация XML - это немного мое домашнее животное... Я стараюсь избегать его любой ценой.

  • 0
    +1 за избежание этого любой ценой.
5

Каждый раз, когда вы можете изменить свой код на данные, вы делаете шаг в правильном направлении.

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

Кроме того, XML файл можно прочитать в графическом интерфейсе или другом инструменте и легко манипулировать прагматически. Как бы вы это сделали с примером кода?

Я постоянно факторизую то, что большинство людей будет внедрять в качестве кода в данные, он делает код остальным MUCH cleaner. Мне кажется немыслимым, что люди создадут меню в коде, а не как данные - должно быть очевидно, что делать это в коде просто неправильно из-за шаблона.

  • 0
    имеет смысл, не думал об этом в этой перспективе
  • 7
    с другой стороны, люди часто идут другим путем и пытаются вставить логику в данные, что означает, что вы в конечном итоге кодируете свое приложение на некачественном языке программирования
Показать ещё 3 комментария
3

У меня есть ваш ответ

В каждом подходе явно имеются компромиссы, но внешние файлы конфигурации XML полезны для развития предприятия, в которых системы сборки используются для компиляции кода, а не для вашей среды IDE. Используя систему сборки, вы можете захотеть ввести определенные значения в свой код - например, версию сборки (которая может быть болезненной при обновлении вручную при каждом компиляции). Боль больше, когда ваша система сборки вытаскивает код из некоторой системы контроля версий. Изменение простых значений во время компиляции потребует от вас изменения файла, его фиксации, компиляции и последующего возврата каждый раз для каждого изменения. Это не изменения, которые вы хотите зафиксировать в своем управлении версиями.

Другие полезные примеры использования системы сборки и внешних конфигураций:

  • вводя стили/таблицы стилей для одной базы кода для разных построек
  • ввод различных наборов динамического содержимого (или ссылок на них) для вашей единой базы кода
  • ввод контекста локализации для разных построек/клиентов
  • изменение URI веб-службы на резервный сервер (когда основной отключается)

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

  • Представьте, что у вас была система, в которой она отслеживала трафик вашего сайта. В зависимости от количества одновременных пользователей он включает/выключает механизм ведения журнала. Возможно, пока механизм выключен, на его место помещается объект-заглушка.
  • Представьте, что у вас была система веб-конференций, в которой в зависимости от количества пользователей вы хотите отключить возможность делать P2P в зависимости от # участников.
  • 0
    +1 за выделение корпоративного аспекта прямо вверху. Тестирование плохо написанного унаследованного кода иногда может быть кошмаром в течение нескольких дней.
3

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

Например, Spring позволяет реализовать интерфейс InitializingBean и добавить метод afterPropertiesSet (вы также можете указать "init-method", чтобы избежать связывания вашего кода с Spring). Эти методы позволят вам убедиться, что любой интерфейс, указанный как поле в экземпляре вашего класса, правильно настроен при запуске, а затем вам больше не нужно проверять ваши получатели и сеттеры (если вы разрешаете вашим синглонам оставаться в потоковом режиме).

Кроме того, гораздо проще выполнять сложные инициализации с контейнером DI вместо того, чтобы делать их самостоятельно. Например, я помогаю использовать XFire (не CeltiXFire, мы используем только Java 1.4). В приложении используется Spring, но, к сожалению, он использовал механизм конфигурации XFire services.xml. Когда в коллекции элементов необходимо объявить, что у нее есть ZERO или больше экземпляров вместо ONE или более экземпляров, мне пришлось переопределить некоторые из предоставленного кода XFire для этой конкретной службы.

В схеме Spring beans определены определенные значения по умолчанию XFire. Итак, если мы использовали Spring для настройки служб, можно было использовать beans. Вместо этого произошло то, что я должен был предоставить экземпляр определенного класса в файле services.xml вместо использования beans. Для этого мне нужно было предоставить конструктор и настроить ссылки, объявленные в конфигурации XFire. Реальное изменение, которое мне нужно было сделать, чтобы перегрузить один класс.

Но, благодаря файлу services.xml, мне пришлось создать четыре новых класса, установив их значения по умолчанию в соответствии с их значениями по умолчанию в конфигурационных файлах Spring в своих конструкторах. Если бы мы могли использовать конфигурацию Spring, я мог бы просто сказать:

<bean id="base" parent="RootXFireBean">
    <property name="secondProperty" ref="secondBean" />
</bean>

<bean id="secondBean" parent="secondaryXFireBean">
    <property name="firstProperty" ref="thirdBean" />
</bean>

<bean id="thirdBean" parent="thirdXFireBean">
    <property name="secondProperty" ref="myNewBean" />
</bean>

<bean id="myNewBean" class="WowItsActuallyTheCodeThatChanged" />

Вместо этого он выглядел примерно так:

public class TheFirstPointlessClass extends SomeXFireClass {
    public TheFirstPointlessClass() {
        setFirstProperty(new TheSecondPointlessClass());
        setSecondProperty(new TheThingThatWasHereBefore());
    }
}

public class TheSecondPointlessClass extends YetAnotherXFireClass {
    public TheSecondPointlessClass() {
        setFirstProperty(TheThirdPointlessClass());
    }
}

public class TheThirdPointlessClass extends GeeAnotherXFireClass {
    public TheThirdPointlessClass() {
        setFirstProperty(new AnotherThingThatWasHereBefore());
        setSecondProperty(new WowItsActuallyTheCodeThatChanged());
    }
}

public class WowItsActuallyTheCodeThatChanged extends TheXFireClassIActuallyCareAbout {
    public WowItsActuallyTheCodeThatChanged() {
    }

    public overrideTheMethod(Object[] arguments) {
        //Do overridden stuff
    }
}

Таким образом, чистый результат состоит в том, что к кодовой базе необходимо добавить четыре дополнительных, в основном бессмысленных Java-класса, чтобы добиться того, что достигнут один дополнительный класс и какая-то простая информация о контейнере зависимостей. Это не "исключение, которое доказывает правило", это правило является правилом... обработка причуд в коде намного чище, когда свойства уже предоставлены в контейнере DI, и вы просто меняете их в соответствии с особой ситуацией, которое происходит чаще, чем нет.

2

Вы можете сложить новую реализацию для подруги. Поэтому новую женщину можно вводить без перекомпиляции кода.

<bean id="jane" class="foo.bar.HotFemale">
  <property name="age" value="19"/>
</bean>
<bean id="mary" class="foo.bar.Female">
  <property name="age" value="23"/>
</bean>
<bean id="john" class="foo.bar.Male">
  <property name="girlfriend" ref="jane"/>
</bean>

(Вышеприведенное предполагает, что Female и HotFemale реализуют тот же интерфейс GirlfFriend)

  • 0
    Почему логические модификации без перекомпиляции считаются хорошей идеей?
  • 0
    Я определенно могу сделать HotFemale jane = new HotFmale (); jane.setAge (19); john.setGirlfriend (джане); Таким образом, единственное отличие состоит в том, что cfg может быть изменен без перекомпиляции? Кажется, это общий ответ, когда обсуждается весна. Зачем?! Почему хорошо избегать компиляции?
Показать ещё 2 комментария
2

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

  • 0
    развертывание? возможно ... сопровождение развёртывания? возможно ... обслуживание кода? Я склонен думать, что нет ... отладка с помощью фреймворков, как правило, является большой головной болью, и с pojos намного легче справиться в этом отношении.
  • 1
    Майк, я ничего не сказал о коде. Мы все знаем, что конфигурация XML отстой :)
Показать ещё 2 комментария
1

Из Spring perspecitve я могу дать вам два ответа.

Сначала конфигурация XML не является единственным способом определения конфигурации. Большинство вещей можно настроить с помощью аннотаций, а вещи, которые должны выполняться с XML, - это конфигурация для кода, который вы не пишете, как пул соединений, который вы используете из библиотеки. Spring 3 включает в себя способ определения конфигурации DI с использованием Java, аналогичный конфигурации с ручной подачей DI в вашем примере. Поэтому использование Spring не означает, что вы должны использовать файл конфигурации на основе XML.

Во-вторых, Spring - это нечто большее, чем просто каркас DI. Он имеет множество других функций, включая управление транзакциями и АОП. Конфигурация XML Spring объединяет все эти концепции вместе. Часто в том же конфигурационном файле я указываю зависимости bean, параметры транзакции и добавление сеанса beans, которое фактически обрабатывается с использованием AOP в фоновом режиме. Я считаю, что конфигурация XML обеспечивает лучшее место для управления всеми этими функциями. Я также чувствую, что настройка на основе аннотаций и конфигурация XML расширяются лучше, чем настройка на основе Java.

Но я вижу вашу точку зрения, и нет ничего плохого в определении конфигурации инъекций зависимостей в Java. Обычно я это делаю в модульных тестах, и когда я работаю над проектом, достаточно маленьким, чтобы я не добавил рамки DI. Обычно я не указываю конфигурацию на Java, потому что для меня этот вид сантехнического кода, который я пытаюсь уйти от написания, когда я решил использовать Spring. Это предпочтение, однако, это не означает, что конфигурация XML превосходит конфигурацию на основе Java.

1

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

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

  • 0
    Это верный момент, но конфигурация пружины часто бывает довольно сложной. Хотя возраст легко изменить, сисадмину все равно приходится иметь дело с большим XML-файлом, который он не совсем понимает. Не лучше ли извлечь часть, которая должна быть сконфигурирована, во что-то еще более простое, чем весенний XML-конфиг? Как и файл свойств, с одной строкой «age = 23» и не позволяет администратору изменять другие детали, такие как имена классов и т. Д., Которые требуют знания внутренней структуры программы.
  • 0
    Недавно я работал над проектом, в котором была смесь кода Java и XSLT. Команда состояла из людей, которые были сильны в Java (и, возможно, менее комфортно работали с XML и XSLT); и люди, которые были очень сильны в работе с XML и XSLT (и менее чувствительны к Java). Поскольку конфигурация собиралась управляться второй группой, имело смысл использовать Spring и иметь XML-конфигурации. Другими словами, Spring решил проблему разделения труда в команде. Это не решило «техническую» проблему; в том смысле, что конфигурация могла бы быть так же легко сделана с помощью кода Java.
Показать ещё 2 комментария
1

Простота объединения частичных конфигураций в окончательную полную конфигурацию.

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


  UI-context.xml
  Model-context.xml
  Controller-context.xml

Или загрузите другой пользовательский интерфейс и несколько дополнительных контроллеров:


  AlternateUI-context.xml
  Model-context.xml
  Controller-context.xml
  ControllerAdditions-context.xml

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

1

В мире .NET большинство инфраструктур IoC обеспечивают конфигурацию XML и кода.

StructureMap и Ninject, например, используют бесплатные интерфейсы для настройки контейнеров. Вам больше не нужно использовать файлы конфигурации XML. Spring, который также существует в .NET, сильно зависит от файлов XML, поскольку он является его историческим основным интерфейсом конфигурации, но по-прежнему можно программировать контейнеры программно.

  • 0
    Здорово, что я наконец-то могу использовать код для того, для чего он предназначен :) Но зачем мне вообще нужно что-то кроме языка программирования, чтобы делать такие вещи?
  • 0
    Я думаю, это потому, что XML допускает изменения во время выполнения или, по крайней мере, изменения конфигурации без перекомпиляции проекта.
0

Инициализация в файле конфигурации XML упростит вашу работу по отладке/адаптации с клиентом, у которого ваше приложение развернуто на своих компьютерах. (Потому что он не требует перекомпиляции + замены двоичных файлов)

0

Spring также имеет загрузчик свойств. Мы используем этот метод для установки переменных, зависящих от среды (например, разработки, тестирования, принятия, производства и т.д.). Это может быть, например, очередь для прослушивания.

Если нет причин, по которым свойство изменилось, нет причин для его настройки таким образом.

0

Ваш случай очень прост и поэтому не нужен контейнер IoC (Inversion of Control), например Spring. С другой стороны, когда вы "программируете интерфейсы, а не реализации" (что является хорошей практикой в ​​ООП), вы можете иметь такой код:

IService myService;
// ...
public void doSomething() {
  myService.fetchData();
}

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

  • Внешняя конфигурация отображения между интерфейсами и их конкретными реализациями
  • Контейнер IoC обрабатывает некоторые сложные проблемы, такие как разрешение сложных графиков зависимостей, управление временем жизни компонента и т.д.
  • Вы сохраняете время кодирования, потому что вы предоставляете сопоставление декларативно, а не в процедурный код
  • Принцип инверсии принципа управления позволяет легко тестировать устройство, поскольку вы можете заменить реальные реализации фальшивыми (например, заменить базу данных SQL на встроенную память).
-2

Одной из наиболее привлекательных причин является " принцип Голливуда:" Не звоните нам, мы позвоним вам. Компонент не обязан выполнять поиск других компонентов и служб; вместо этого они предоставляются ему автоматически. В Java это означает, что больше не нужно делать JNDI-запросы внутри компонента.

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

  • 0
    Этот ответ о внедрении зависимости. Я знаю, что это, я знаю, что это хорошо, и я четко заявляю об этом в первом предложении вопроса. Вопрос был о преимуществах конфигурации DI по сравнению с простым кодом инициализации.
  • 0
    На самом деле не отвечает на вопрос

Ещё вопросы

Сообщество Overcoder
Наверх
Меню