Слова invert
или control
вообще не используются для определения инверсии контроля в определениях, которые я видел.
Определения
Википедия
инверсия управления (IoC) - это метод программирования, выраженный здесь в терминах объектно-ориентированного программирования, в котором связывание объектов во время выполнения связано с ассемблерным объектом и обычно не известно во время компиляции с использованием статического анализа. ~ http://en.wikipedia.org/wiki/Inversion_of_control
Мартин Фаулер
Инверсия управления - это распространенный шаблон в сообществе Java, который помогает объединять легкие контейнеры или собирать компоненты из разных проектов в единое приложение. ~ основано на http://www.martinfowler.com/articles/injection.html (перефразировано)
Так почему Inversion of Control называется Inversion of Control? Какой контроль инвертируется и чем? Есть ли способ определить инверсию управления, используя терминологию: инвертировать и контролировать ?
источник
Ответы:
Допустим, у вас есть какой-то класс «репозитория», и этот репозиторий отвечает за передачу вам данных из источника данных.
Хранилище может само установить соединение с источником данных. Но что, если он позволяет передавать соединение с источником данных через конструктор хранилища?
Позволяя вызывающей стороне предоставлять соединение, вы отделяете зависимость соединения с источником данных от класса репозитория, позволяя любому источнику данных работать с репозиторием, а не только тому, который указан в репозитории.
Вы перевернули управление , передав ответственность за создание соединения из класса репозитория вызывающей стороне.
Мартин Фаулер предлагает использовать термин «внедрение зависимостей» для описания этого типа инверсии управления, поскольку инверсию управления как концепцию можно применять более широко, чем просто введение зависимостей в метод конструктора.
источник
Я не думаю, что кто-то может объяснить это лучше, чем Мартин Фаулер, далее в статье, на которую вы ссылались .
Как он объясняет в параграфах выше, это не совсем то же самое, что и причина возникновения термина «инверсия контроля».
Вот почему он продолжает использовать термин «Внедрение зависимостей», чтобы охватить эту конкретную реализацию «Инверсии контроля».
Чтобы немного уточнить: инверсия управления означает все, что инвертирует структуру управления программы из классического процедурного дизайна.
В былые времена ключевым примером этого было позволить платформе обрабатывать связь между пользовательским интерфейсом и вашим кодом, а не оставлять свой код для непосредственного создания пользовательского интерфейса.
В более недавние времена (когда такие структуры в значительной степени доминировали, поэтому вопрос больше не был актуален), примером был инвертирование контроля над созданием объектов.
Фаулер и другие решили, что термин «инверсия контроля» охватывает слишком много методов, и нам нужен был новый термин для конкретного примера создания объектов (внедрение зависимости), но к моменту заключения соглашения фраза «Контейнер IoC» "снял.
Это сильно мутит воду, потому что контейнер IoC - это особый тип инъекции зависимости, а инъекция зависимости - это особый вид инверсии контроля. Вот почему вы получаете такие запутанные ответы, независимо от того, где вы смотрите.
источник
Вот «обычные» программы управления потоком, которые обычно следуют:
Инверсия управления «инвертирует» этот поток управления, то есть он переворачивает его на голову:
Эта последняя строка является важной. Вместо того, чтобы звонить кому-то другому, когда вам это нравится, кто-то еще звонит вам, когда ему это нравится.
Типичным примером этого являются веб-фреймворки, такие как Rails. Вы определяете контроллеры, но на самом деле вы не решаете, когда они будут вызваны. Rails вызывает их, когда решает, что в этом есть необходимость.
источник
Это о том, кто контролирует создание зависимостей.
Традиционно, когда класс / метод должен использовать другой класс (зависимость), он создается экземпляром класса / метода напрямую. Он контролирует свои зависимости.
С помощью Inversion of Control (IoC) вызывающая сторона передала зависимость, следовательно, она создает зависимость. Вызывающая сторона контролирует зависимости.
Элемент управления тем, где создается зависимость, был инвертирован - вместо того, чтобы находиться в «низу», где находится код, в котором он нуждается, он создается в «верху», где вызывается код, который нуждается в этом.
источник
Обычно код более высокого уровня вызывает (т.е. контролирует) код более низкого уровня. Main () вызывает функцию (), функция () вызывает функцию libraryFunction ().
Это может быть инвертировано, поэтому низкоуровневая библиотечная функция внизу вызывает функции более высокого уровня.
Почему ты бы так поступил? Middleware. Иногда вы хотите контролировать верхний и нижний уровни, но в середине много работы, которую вы просто не хотите делать. Возьмите реализацию быстрой сортировки в C stdlib . Вы называете быстрой сортировкой на верхнем уровне. Вы передаете qsort () функциональный указатель на вашу собственную функцию, которая реализует компаратор для всего, что вы чувствуете. Когда вызывается qsort (), он вызывает функцию сравнения. qsort () контролирует / вызывает / управляет вашей высокоуровневой функцией.
источник
Вот простой обзор:
В былые времена управление принадлежало приложению первым, а пользователю - второму. Если приложению нужно что-то от пользователя, оно остановится и спросит, а затем перейдет к следующей задаче. Взаимодействие с пользователем предоставляло в основном данные, а не управляло тем, что приложение делало дальше. В наше время это немного чуждо нам, так как мы не видим такого поведения очень часто.
Если мы переключим это и дадим пользователю первичный контроль, то мы изменили управление. Это означает, что вместо пользователя, ожидающего, пока приложение что-то сделает, приложение будет сидеть и ждать, пока пользователь что-то сделает. Графический интерфейс пользователя - отличный пример этого, и почти все, что связано с циклом событий, имеет инвертированное управление.
Обратите внимание, что мой пример находится на верхнем уровне, и что эта концепция инверсии управления может быть абстрагирована к различным уровням управления в приложении (т.е. внедрение зависимости). Возможно, поэтому так сложно получить прямой ответ.
источник
Давайте попробуем понять это на двух примерах.
Пример 1
В прежние времена приложения, используемые для генерации командных приглашений, принимали пользовательские вводы один за другим Сегодня фреймворки пользовательского интерфейса создают экземпляры различных элементов пользовательского интерфейса, перебирая различные события этих элементов пользовательского интерфейса (например, наведение мыши, щелчок и т. Д.), А пользовательские / основные программы предоставляют хуки (например, прослушиватели событий пользовательского интерфейса в Java) для прослушивания этих событий. Таким образом, основной поток элементов управления «контроль» перемещается из пользовательской программы в среду пользовательского интерфейса. В прежние времена это было в пользовательской программе.
Пример 2
Рассмотрим класс
CustomerProcessor
ниже:Если я хочу
processCustomer()
быть независимым от какой-либо реализацииgetAllCusts()
, а не только от той, которая предоставленаSqlCustRepo
, мне нужно будет избавиться от строки:SqlCustRepo custRepo = new SqlCustRepo()
и заменить ее чем-то более общим, способным принимать различные типы реализаций, так что ониprocessCustomers()
будут просто работать для любая предоставленная реализация. Вышеупомянутый код (создание необходимого класса сSqlCustRepo
помощью логики основной программы) является традиционным способом, и он не достигает этой цели отделенияprocessCustomers()
от реализацииgetAllCusts()
. При инверсии управления контейнер создает экземпляр необходимого класса реализации (как указано, скажем, в конфигурации xml), внедряет его в логику основной программы, которая связывается в соответствии с указанными хуками (скажем, с помощью@Autowired
аннотации илиgetBean()
метода в среде Spring).Посмотрим, как это можно сделать. Рассмотрим код ниже.
Config.xml
CustRepo.java
JsonCustRepo.java
App.java
Мы также можем иметь
а также
и нам не нужно будет менять App.java.
Над контейнером (который является платформой Spring) лежит ответственность за сканирование XML-файла, создание экземпляра bean-компонента определенного типа и внедрение его в пользовательскую программу. Пользовательские программы не имеют контроля над тем, какой класс создается.
PS: IoC является общей концепцией и достигается многими способами. Приведенные выше примеры достигают этого путем внедрения зависимости.
Ссылка: статья Мартина Фаулера .
источник