Что подразумевается под "инверсией" в инверсии зависимости

Я учу весну. Я понял внедрение зависимости. В каком-то месте я также вижу это как инверсию зависимости. Я понял, почему это называется впрыском, но что подразумевается под "инверсией"? Какая зависимость на самом деле инвертируется?

3 ответа

Решение

Хороший вопрос - слово inversion несколько удивительно (поскольку после применения DIP модуль зависимостей более низкого уровня, очевидно, не depend в модуле вызывающего абонента более высокого уровня - и вызывающий, и зависимость теперь просто более слабо связаны через дополнительную абстракцию).

Ссылаясь на первоисточник Роберта С. Мартина

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

Стоит отметить, что при чтении статьи дяди Боба о DIP у C++ не было (и на момент написания все еще не было) интерфейсов, поэтому достижение этой абстракции в C++ обычно реализуется через абстрактный / чистый виртуальный базовый класс. в то время как в Java или C# абстракция для ослабления связи обычно происходит через развязку путем абстрагирования интерфейса от зависимости и связывания модуля (модулей) более высокого уровня с интерфейсом.

Редактировать Просто чтобы уточнить:

"В каком-то месте я также вижу это как инверсию зависимости"

Обратите внимание, что Dependency Injection (DI) является ОДНОЙ из возможных реализаций для достижения Принципа инверсии зависимостей (DIP) - "D" в принципах SOLID, поэтому DI а также DIP не являются полностью взаимозаменяемыми.

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

Инверсия: инвертирование управления зависимостями из приложения в контейнер (например, Spring).

Внедрение зависимости:

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

Так что насчет инверсии контроля (IoC)?

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

Инверсия управления в качестве руководства по проектированию служит следующим целям:

  • Происходит разделение выполнения определенной задачи от реализации.
  • Каждый модуль может сосредоточиться на том, для чего он предназначен.
  • Модули не делают никаких предположений о том, что делают другие системы, но полагаются на свои контракты.
  • Замена модулей не оказывает побочного влияния на другие модули.

Для получения дополнительной информации взгляните на:

Шаблон проектирования МОК и ДИ.

Шаблон проектирования - инверсия управления и внедрение зависимостей.

Практическое введение в инверсию контроля.

Шаблоны инверсии контроля (IoC) и внедрения зависимостей (DI) в весенних рамках и связанные с ними вопросы интервью.

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

Рассмотрим упрощенный пример.

  • В «плохом» приложении зависит от: наш сервис зависит от реализации базы данных. Примечательно, что наш сервис зависит от «вещи» более низкого уровня.
  • В "хорошем" приложении зависит от DatabaseInterface, который, в свою очередь, реализуется. А поскольку интерфейс считается абстракцией более высокого уровня, чем сервис, наш сервис теперь зависит от «вещи» более высокого уровня.

Теперь в некотором смысле направленность зависимости не изменилась. На практике до сих пор косвенно зависит от. Стоит подчеркнуть, что когда мы говорим, что инвертировали зависимости, мы НЕ имеем в виду, что BarDatabase теперь как-то зависит от FooService.

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

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

Ссылки: Что инвертирует в принципе инверсии зависимостей?

Другие вопросы по тегам