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

StackOverflow https://stackoverflow.com/questions/131975

Вопрос

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


ОБНОВЛЯТЬ:
В случае

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, где сопоставление между свойством компонента и столбцом БД используется для сохранения, загрузки, построения поисковых запросов и т. д.Конфигурацию Spring DI можно легко перевести в код настройки, как в начале этого вопроса, не так ли?И он используется только для инициализации компонента, не так ли?Значит, декларативный подход здесь ничего не добавляет?

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


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

Это было полезно?

Решение

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

  • Тестирование
  • Обслуживание производства

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

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

  1. Модульное тестирование
  2. Интеграционное тестирование
  3. Тестирование черного ящика

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

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

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

Производство

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

Краткое содержание

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

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

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

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

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

Другие советы

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

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

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

  1. Код DI гораздо проще использовать повторно, поскольку «зависимые» функции экстраполируются в четко определенные интерфейсы, что позволяет по желанию подключать отдельные объекты, конфигурация которых обрабатывается подходящей платформой приложения, к другим объектам.
  2. Код DI гораздо проще тестировать.Функциональность, выраженную объектом, можно протестировать в «черном ящике», создав «фиктивные» объекты, реализующие интерфейсы, ожидаемые логикой вашего приложения.
  3. Код DI более гибок.Это изначально слабосвязанный код — до крайности.Это позволяет программисту выбирать способ соединения объектов исключительно на основе необходимых им интерфейсов на одном конце и их выраженных интерфейсов на другом.
  4. Внешняя (Xml) конфигурация объектов DI означает, что другие могут настраивать ваш код в непредвиденных направлениях.
  5. Внешняя конфигурация также представляет собой шаблон разделения ответственности, поскольку все проблемы инициализации объектов и управления взаимозависимостью объектов могут решаться сервером приложений.
  6. Обратите внимание, что для использования шаблона DI не требуется внешняя настройка, для простых взаимосвязей часто бывает достаточно небольшого объекта-строителя.Между ними существует компромисс в гибкости.Объект-строитель не является таким гибким вариантом, как видимый извне файл конфигурации.Разработчик системы DI должен взвесить преимущества гибкости перед удобством, позаботившись о том, чтобы мелкомасштабный и детальный контроль над построением объекта, выраженный в файле конфигурации, мог привести к путанице и затратам на обслуживание в дальнейшем.

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

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

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

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

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

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

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

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

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

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

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

Я постоянно учитываю то, что большинство людей реализовали бы в виде кода, в данные, и это делает код НАМНОГО чище.Я считаю невероятным, чтобы люди создавали меню в коде, а не в виде данных — должно быть очевидно, что делать это в коде просто неправильно из-за шаблона.

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

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

Более того, гораздо проще выполнять сложную инициализацию с помощью DI-контейнера, чем делать это самостоятельно.Например, я помогаю использовать XFire (не CeltiXFire, мы используем только Java 1.4).Приложение использовало Spring, но, к сожалению, использовало механизм конфигурации Services.xml XFire.Когда Коллекции элементов нужно было объявить, что она имеет НОЛЬ или более экземпляров вместо ОДНОГО или более экземпляров, мне пришлось переопределить часть предоставленного кода XFire для этой конкретной службы.

В схеме компонентов Spring определены определенные значения по умолчанию для XFire.Итак, если бы мы использовали Spring для настройки сервисов, можно было бы использовать bean-компоненты.Вместо этого мне пришлось предоставить экземпляр определенного класса в файле Services.xml вместо использования bean-компонентов.Для этого мне нужно было предоставить конструктор и настроить ссылки, объявленные в конфигурации 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-контейнере, и вы просто меняете их в соответствии с особой ситуацией. что происходит чаще всего.

у меня есть твой ответ

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

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

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

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

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

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

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

<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)

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

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

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

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

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

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

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

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

Часто важным моментом является ВОЗ меняет конфигурацию после написания программы.Используя конфигурацию в коде, вы неявно предполагаете, что человек, меняющий ее, имеет те же навыки и доступ к исходному коду и т. д., что и первоначальный автор.

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

С точки зрения Spring я могу дать вам два ответа.

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

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top