На уровне класса это легко.
«Внедрение зависимостей» просто отвечает на вопрос «как я найду моих сотрудников»: «Они на тебя давят - тебе не нужно идти и брать их самому». (Это похоже - но не то же самое, что и «Инверсия контроля», где на вопрос «как я упорядочу свои операции над своими входами?» Есть аналогичный ответ).
Только выгоды , которые имеют ваши сотрудники толкнули вас, что позволяет клиентский коду использовать класс , чтобы составить граф объекта , который соответствует его нынешней потребности ... Вы не произвольно предварительно определили форму и переменчивость графы приватно принятия решения конкретные типы и жизненный цикл ваших сотрудников.
(Все эти другие преимущества, связанные с тестируемостью, слабой связью и т. Д., В значительной степени вытекают из использования интерфейсов, а не столько из-за внедрения зависимости, хотя DI естественным образом способствует использованию интерфейсов).
Стоит отметить, что, если вы избегаете создания экземпляров своих собственных соавторов, ваш класс должен поэтому получать своих соавторов из конструктора, свойства или аргумента метода (кстати, этот последний параметр часто упускается из виду ... он делает не всегда имеет смысл, чтобы класс «соавторы» был частью его «состояния»).
И это хорошо.
На уровне приложения ...
Так много для индивидуального взгляда на вещи. Допустим, у вас есть куча классов, которые следуют правилу «не создавайте экземпляры ваших собственных соавторов» и хотите создать из них приложение. Самое простое, что можно сделать - это использовать старый добрый код (действительно полезный инструмент для вызова конструкторов, свойств и методов!), Чтобы составить нужный вам граф объектов и добавить к нему некоторую информацию. (Да, некоторые из этих объектов в вашем графе сами по себе будут объектными фабриками, которые были переданы в качестве соавторов другим долгоживущим объектам в графе, готовым к работе ... вы не можете предварительно построить каждый объект! ).
... вам нужно «гибко» настраивать объект-граф вашего приложения ...
В зависимости от ваших других (не связанных с кодом) целей, вы можете захотеть дать конечному пользователю некоторый контроль над развернутым графом объектов. Это ведет вас в направлении схемы конфигурации того или иного типа, будь то текстовый файл вашего собственного дизайна с некоторыми парами имя / значение, файл XML, пользовательский DSL, декларативный язык описания графов, такой как YAML, императивный язык сценариев, такой как JavaScript, или что-то еще, соответствующее поставленной задаче. Все, что нужно для составления правильного графа объектов, таким образом, чтобы удовлетворить потребности ваших пользователей.
... может быть значительным конструктивным фактором.
В самых экстремальных обстоятельствах этого типа вы можете выбрать очень общий подход и дать конечным пользователям общий механизм для «привязки» объекта-графа по своему выбору и даже позволить им предоставлять конкретные реализации интерфейсов для во время выполнения! (Ваша документация - блестящая жемчужина, ваши пользователи очень умны, знакомы, по крайней мере, с грубым контуром графа объектов вашего приложения, но у вас нет удобного компилятора). Этот сценарий теоретически может возникнуть в некоторых «корпоративных» ситуациях.
В этом случае у вас, вероятно, есть декларативный язык, который позволяет вашим пользователям выражать любой тип, композицию графов объектов таких типов и палитру интерфейсов, которые мифический конечный пользователь может смешивать и сопоставлять. Чтобы уменьшить когнитивную нагрузку на ваших пользователей, вы предпочитаете подход «конфигурация по соглашению», так что им нужно только вмешаться и обойти интересующий объект-граф-фрагмент, а не бороться со всем этим.
Вы бедняга!
Поскольку вам не хотелось писать все это самостоятельно (а если серьезно, проверьте привязку YAML для вашего языка), вы используете какую-то инфраструктуру DI.
В зависимости от зрелости этой среды у вас может не быть возможности использовать конструктор-инъекцию, даже когда это имеет смысл (соавторы не меняются в течение срока службы объекта), что вынуждает вас использовать Setter Injection (даже когда коллабораторы не изменяются в течение всего срока службы объекта, и даже если на самом деле нет логической причины, по которой все конкретные реализации интерфейса должны иметь коллабораторов определенного типа). Если это так, то вы в настоящее время находитесь в аду сильной связи, несмотря на то, что старательно «использовали интерфейсы» по всей вашей кодовой базе - ужас!
Надеюсь, однако, что вы использовали DI-фреймворк, который дает вам возможность внедрения конструктора, и ваши пользователи лишь немного раздражительны из- за того, что вы не тратите больше времени на размышления о конкретных вещах, которые им нужны для настройки, и предоставления им пользовательского интерфейса, более подходящего для этой задачи. под рукой. (Хотя, если быть честным, вы, вероятно, пытались придумать способ, но JavaEE подвела вас, и вам пришлось прибегнуть к этому ужасному хаку).
Bootnote
Ни в коем случае вы никогда не используете Google Guice, который дает вам кодеру способ избавиться от задачи составления графов объектов с помощью кода ... путем написания кода. Argh!