Согласно статье, написанной Мартином Фаулером , инверсия управления является принципом, в котором поток управления программы инвертируется: вместо программиста, управляющего потоком программы, внешние источники (инфраструктура, службы, другие компоненты) принимают на себя управление Это. Как будто мы подключаем что-то к чему-то другому. Он привел пример с EJB 2.0:
Например, интерфейс Session Bean определяет ejbRemove, ejbPassivate (сохраняется во вторичном хранилище) и ejbActivate (восстанавливается из пассивного состояния). Вы не можете контролировать, когда эти методы вызываются, только то, что они делают. Контейнер звонит нам, мы не называем это.
Это приводит к разнице между фреймворком и библиотекой:
Инверсия управления - это ключевая часть того, что отличает фреймворк от библиотеки. Библиотека - это, по сути, набор функций, которые вы можете вызывать, в наши дни обычно организованные в классы. Каждый звонок выполняет некоторую работу и возвращает управление клиенту.
Я думаю, точка зрения, что DI - это IOC, означает, что зависимость объекта инвертирована: вместо того, чтобы управлять своими собственными зависимостями, жизненным циклом ... что-то другое делает это за вас. Но, как вы сказали мне о DI руками, DI не обязательно является МОК. У нас еще может быть DI и нет МОК.
Однако в этой статье (из pococapsule, другой IOC Framework для C / C ++) предполагается, что из-за IOC и DI контейнеры IOC и структуры DI намного превосходят J2EE, поскольку J2EE смешивает код инфраструктуры с компонентами. таким образом, не делая его простым простым Java / C ++ объектом (POJO / POCO).
Инверсия управляющих контейнеров, отличных от шаблона внедрения зависимостей (ссылка на архив)
Дополнительное чтение, чтобы понять, в чем проблема со старой платформой разработки на основе компонентов, что приводит ко второй статье выше: почему и что такое Inversion of Control (ссылка на архив)
Мой вопрос : что такое МОК и ДИ? Я запутался. Основанный на pococapsule, IOC является чем-то более значительным, чем просто инверсия управления между объектами или программистами и средами.
Ответы:
IoC - это общий термин, означающий, что приложение не вызывает методы в платформе, а платформа вызывает реализации, предоставляемые приложением.
DI - это форма IoC, где реализации передаются в объект через поиск конструкторов / установщиков / служб, от которого объект будет «зависеть» для правильного поведения.
Например, IoC без использования DI будет шаблоном шаблона, потому что реализация может быть изменена только с помощью подклассов.
DI Frameworks предназначены для использования DI и могут определять интерфейсы (или аннотации в Java), чтобы упростить передачу реализаций.
Контейнеры IoC - это структуры DI, которые могут работать за пределами языка программирования. В некоторых вы можете настроить, какие реализации использовать в файлах метаданных (например, XML), которые менее инвазивны. С некоторыми вы можете сделать IoC, что обычно невозможно, например, внедрить реализацию в pointcuts .
Смотрите также эту статью Мартина Фаулера .
источник
Короче говоря, IoC - это гораздо более широкий термин, который включает, но не ограничивается, DI
Термин Inversion of Control (IoC) первоначально означал любой стиль программирования, когда общая среда или среда выполнения контролировали ход программы.
До того, как у DI появилось имя, люди начали ссылаться на структуры, которые управляют зависимостями, как инверсию контейнеров управления, и вскоре значение IoC постепенно сместилось к этому конкретному значению: инверсия контроля над зависимостями.
Инверсия управления (IoC) означает, что объекты не создают другие объекты, на которые они полагаются при выполнении своей работы. Вместо этого они получают нужные им объекты из внешнего источника (например, файла конфигурации xml).
Внедрение зависимостей (DI) означает, что это выполняется без вмешательства объекта, обычно с помощью компонента инфраструктуры, который передает параметры конструктора и задает свойства.
источник
источник
IoC ( я nversion о е C ontrol): - Это общий термин , и реализуется несколькими способами (события, делегаты и т.д.).
DI ( D ependency I njection): - DI является подтипом IoC и реализуется путем инъекции конструктора, инъекции сеттера или инъекции интерфейса .
Но Spring поддерживает только следующие два типа:
NullPointerException: bean does not exist
. Внедрение в конструктор - это лучшая практика для внедрения зависимостей.источник
DI является подмножеством IoC
Вот некоторые другие методы для достижения IoC .
источник
IOC (Inversion Of Control) : Предоставление контроля контейнеру для получения экземпляра объекта называется Inversion of Control. Это означает, что вместо того, чтобы создавать объект с помощью оператора new, пусть контейнер сделает это за вас.
DI (Dependency Injection) : способ внедрения свойств в объект называется Dependency Injection .
У нас есть три типа внедрения зависимостей :
Spring поддерживает только Constructor Injection и Setter / Getter Injection .
источник
Поскольку все ответы подчеркивают теорию, я хотел бы продемонстрировать на примере первого подхода:
Предположим, мы создаем приложение, которое содержит функцию отправки SMS-сообщений с подтверждением после отправки заказа. У нас будет два класса, один отвечает за отправку SMS (SMSService), а другой отвечает за сбор пользовательских данных (UIHandler), наш код будет выглядеть следующим образом:
Вышеприведенная реализация не является неправильной, но есть несколько проблем:
-) Предположим, что в среде разработки вы хотите сохранить SMS, отправленные в текстовый файл вместо использования шлюза SMS, чтобы достичь этого; мы закончим тем, что изменили конкретную реализацию (SMSService) на другую реализацию, мы теряем гибкость и вынуждены переписывать код в этом случае.
-) Мы закончим смешивать обязанности классов, наш (UIHandler) никогда не должен знать о конкретной реализации (SMSService), это должно быть сделано вне классов с использованием «Интерфейсов». Когда это будет реализовано, это даст нам возможность изменить поведение системы путем замены (SMSService), используемого с другим фиктивным сервисом, который реализует тот же интерфейс, этот сервис будет сохранять SMS-сообщения в текстовом файле вместо отправки на mobileNumber.
Чтобы исправить вышеуказанные проблемы, мы используем интерфейсы, которые будут реализованы нашим (SMSService) и новым (MockSMSService), в основном новый интерфейс (ISMSService) будет демонстрировать такое же поведение обеих служб, как и код ниже:
Затем мы изменим нашу (SMSService) реализацию для реализации интерфейса (ISMSService):
Теперь мы сможем создать новый макетный сервис (MockSMSService) с совершенно другой реализацией, используя тот же интерфейс:
На этом этапе мы можем изменить код в (UIHandler), чтобы легко использовать конкретную реализацию службы (MockSMSService), как показано ниже:
Мы достигли большой гибкости и реализовали разделение проблем в нашем коде, но все же нам нужно внести изменения в кодовую базу для переключения между двумя службами SMS. Поэтому нам нужно внедрить Dependency Injection .
Чтобы достичь этого, нам нужно реализовать изменение в нашем (UIHandler) конструкторе класса, чтобы передать через него зависимость, тем самым код, который использует (UIHandler), может определить, какую конкретную реализацию (ISMSService) использовать:
Теперь форма UI, которая будет общаться с классом (UIHandler), отвечает за передачу используемой реализации интерфейса (ISMSService). Это означает, что мы инвертировали элемент управления (UIHandler) больше не отвечает за решение, какую реализацию использовать, вызывающий код делает. Мы внедрили принцип инверсии управления, одним из которых является DI.
Код формы пользовательского интерфейса будет таким, как показано ниже:
источник
Но весенняя документация говорит, что они одинаковы.
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-introduction
В первой строке « IoC также известен как внедрение зависимостей (DI) ».
источник
IoC - Инверсия управления - это общий термин, независимый от языка, он на самом деле не создает объекты, а описывает, в каком режиме создается объект моды.
DI - Dependency Injection - это конкретный термин, в котором мы предоставляем зависимости объекта во время выполнения, используя различные методы внедрения, а именно. Инъекция сеттера, инжектор конструктора или интерфейсная инъекция.
источник
Инверсия контроля - это парадигма проектирования, цель которой - обеспечить больший контроль над целевыми компонентами вашего приложения, которые выполняют работу.
Внедрение зависимостей - это шаблон, используемый для создания экземпляров объектов, на которые полагаются другие объекты, не зная во время компиляции, какой класс будет использоваться для предоставления этих функций.
Существует несколько основных методов реализации инверсии управления. Эти:
1). Конструктор инъекций
2). Сеттер впрыска
3). Внедрение интерфейса
источник
DI и IOC - это два шаблона проектирования, которые в основном направлены на обеспечение слабой связи между компонентами или просто на способ, которым мы отделяем обычные отношения зависимости между объектами, чтобы объекты не были связаны друг с другом.
Следующими примерами я пытаюсь объяснить обе эти концепции.
Ранее мы пишем такой код
С внедрением Dependency, инжектор зависимостей позаботится о создании объектов
Вышеупомянутый процесс передачи управления некоторому другому (например, контейнеру) для создания экземпляра и внедрения может быть назван инверсией управления, а процесс, в котором контейнер IOC вводит зависимость для нас, может быть назван внедрением зависимости.
IOC - это принцип, в котором управляющий поток программы инвертируется: вместо программиста, управляющего потоком программы , программа управляет потоком, уменьшая накладные расходы для программиста. Процесс, используемый программой для внедрения зависимости, называется DI
Эти две концепции работают вместе, предоставляя нам возможность писать гораздо более гибкий, многократно используемый и инкапсулированный код, что делает их важными концепциями при разработке объектно-ориентированных решений.
Также рекомендую прочитать.
Что такое внедрение зависимостей?
Вы также можете проверить один из моих похожих ответов здесь
Разница между инверсией контроля и инъекцией зависимостей
источник
Inversion of Control - это общий принцип проектирования архитектуры программного обеспечения, который помогает создавать модульные программные структуры многократного использования, которые просты в обслуживании.
Это принцип разработки, при котором поток управления «принимается» из общей библиотеки или кода многократного использования.
Чтобы понять это лучше, давайте посмотрим, как мы использовали кодирование в наши ранние дни кодирования. В процедурных / традиционных языках бизнес-логика, как правило, контролирует поток приложения и «вызывает» общий или повторно используемый код / функции. Например, в простом консольном приложении мой поток управления контролируется инструкциями моей программы, которые могут включать в себя вызовы некоторых общих повторно используемых функций.
В отличие от этого, с IoC, фреймворки представляют собой повторно используемый код, который «вызывает» бизнес-логику.
Например, в системе на основе Windows уже будет доступна инфраструктура для создания элементов пользовательского интерфейса, таких как кнопки, меню, окна и диалоговые окна. Когда я пишу бизнес-логику своего приложения, это будут события фреймворка, которые будут вызывать мой код бизнес-логики (когда событие запускается), а НЕ наоборот.
Хотя код фреймворка не знает о моей бизнес-логике, он все равно будет знать, как вызывать мой код. Это достигается с помощью событий / делегатов, обратных вызовов и т. Д. Здесь управление потоком является «инвертированным».
Таким образом, вместо зависимости потока управления от статически связанных объектов, поток зависит от общего графа объектов и отношений между различными объектами.
Внедрение зависимостей - это шаблон проектирования, в котором реализован принцип IoC для разрешения зависимостей объектов.
Проще говоря, когда вы пытаетесь написать код, вы будете создавать и использовать разные классы. Один класс (класс A) может использовать другие классы (класс B и / или D). Итак, класс B и D являются зависимостями класса A.
Простая аналогия будет классом автомобилей. Автомобиль может зависеть от других классов, таких как двигатель, шины и многое другое.
Внедрение зависимостей предполагает, что вместо зависимых классов (здесь Class Car), создающих свои зависимости (Class Engine и класс Tire), класс должен быть внедрен с конкретным экземпляром зависимости.
Давайте разберемся с более практичным примером. Учтите, что вы пишете свой собственный TextEditor. Среди прочего, вы можете иметь проверку орфографии, которая предоставляет пользователю возможность проверить опечатки в его тексте. Простая реализация такого кода может быть:
На первый взгляд все выглядит радужно. Пользователь напишет какой-нибудь текст. Разработчик захватит текст и вызовет функцию CheckSpellings и найдет список опечаток, которые он покажет пользователю.
Кажется, все работает отлично, пока в один прекрасный день один пользователь не начнет писать по-французски в редакторе.
Чтобы обеспечить поддержку большего количества языков, нам нужно иметь больше SpellCheckers. Вероятно, французский, немецкий, испанский и т. Д.
Здесь мы создали тесно связанный код с «английским» SpellChecker, тесно связанным с нашим классом TextEditor, что означает, что наш класс TextEditor зависит от EnglishSpellChecker или, другими словами, EnglishSpellCheker является зависимостью для TextEditor. Нам нужно удалить эту зависимость. Кроме того, нашему текстовому редактору нужен способ хранить конкретную ссылку любой программы проверки орфографии на основе усмотрения разработчика во время выполнения.
Итак, как мы видели во введении DI, он предлагает вводить класс с его зависимостями. Таким образом, вызывающий код должен нести ответственность за внедрение всех зависимостей в вызываемый класс / код. Таким образом, мы можем реструктурировать наш код как
В нашем примере класс TextEditor должен получить конкретный экземпляр типа ISpellChecker.
Теперь зависимость может быть введена в Constructor, Public Property или метод.
Давайте попробуем изменить наш класс, используя Constructor DI. Измененный класс TextEditor будет выглядеть примерно так:
Чтобы вызывающий код при создании текстового редактора мог внедрить соответствующий тип SpellChecker в экземпляр TextEditor.
Вы можете прочитать полную статью здесь
источник
IOC (Inversion Of Control): Предоставление контроля контейнеру для получения экземпляра объекта называется Inversion of Control. Это означает, что вместо того, чтобы создавать объект с помощью оператора new , пусть контейнер сделает это за вас.
DI (Dependency Injection). Передача необходимых параметров (свойств) из XML в объект (в POJO CLASS) называется внедрением Dependency Injection .
источник
IOC указывает, что внешние классы управляют классами приложения, а внешние классы означают, что контейнер управляет зависимостью между классом приложения. Основная концепция IOC заключается в том, что программисту не нужно создавать ваши объекты, а описывать, как они должны создаваться.
Основные задачи, выполняемые контейнером IoC: создание экземпляра класса приложения. настроить объект. собрать зависимости между объектами.
DI - это процесс предоставления зависимостей объекта во время выполнения с использованием внедрения сеттера или конструктора.
источник
IOC (Inversion of Control) - это, по сути, концепция шаблона проектирования, заключающаяся в удалении зависимостей и их разделении, чтобы сделать поток нелинейным, и позволить контейнеру / или другому объекту управлять предоставлением зависимостей. Это на самом деле следует голливудскому принципу «Не звоните нам, мы вам позвоним». Итак, подытоживая различия.
Инверсия управления: - это общий термин для разделения зависимостей и делегирования их предоставления, и это может быть реализовано несколькими способами (события, делегаты и т. Д.).
Внедрение зависимостей: - DI является подтипом IOC и реализуется путем инжекции в конструктор, вложения метода или метода.
Следующая статья описывает это очень аккуратно.
https://www.codeproject.com/Articles/592372/Dependency-Injection-DI-vs-Inversion-of-Control-IO
источник
Я думаю, что идея может быть продемонстрирована ясно, не вдаваясь в объектно-ориентированные сорняки, которые, кажется, запутывают идею.
Если вы наклоните голову и покоситесь, вы увидите, что DI - это конкретная реализация IoC с конкретными проблемами. Вместо того, чтобы внедрять модели и поведения в структуру приложения или операцию более высокого порядка, вы вводите переменные в функцию или объект.
источник
Давайте начнем с D SOLID и посмотрим на DI и IoC из книги Скотта Миллета «Профессиональные шаблоны проектирования ASP.NET»:
Millett, C (2010). Профессиональные шаблоны проектирования ASP.NET. Wiley Publishing. 7-8.
источник
// ICO, DI, 10 лет назад, вот так:
Теперь с весны 3,4 или последним, как показано ниже
В целом элемент управления инвертируется из старой концепции связанного кода в такие среды, как Spring, что делает объект доступным. Так что, насколько я знаю, это IOC и внедрение зависимостей, как вы знаете, когда мы внедряем зависимый объект в другой объект, используя конструктор или сеттеры. Inject в основном означает передачу его в качестве аргумента. Весной у нас есть конфигурация на основе XML и аннотаций, в которой мы определяем объект bean и передаем зависимый объект в стиле Constructor или setter.
источник
Я нашел лучший пример на Dzone.com, который действительно помогает понять реальные различия между IOC и DI
Читать статью полностью IOC и Читать статью DI полностью
источник
1) DI - это Child-> obj, зависит от parent-obj. Глагол зависит важно. 2) МОК - это Child-> obj, выступающий под платформой. где платформой может быть школа, колледж, танцевальный класс. Здесь выполняются действия с различными последствиями под любым поставщиком платформы.
практический пример: `
`
-AB
источник
Что касается этого вопроса, я бы сказал, что вики уже предоставила подробные и понятные объяснения. Я просто процитирую наиболее значимые здесь.
Внедрение IoC
Что касается внедрения зависимости
источник
Концепция IoC была первоначально услышана в эпоху процедурного программирования. Поэтому из исторического контекста IoC говорил об инверсии владения потоком управления, то есть о том, кто несет ответственность за вызов функций в нужном порядке - будь то сами функции или вы должны инвертировать их в какой-то внешний объект.
Однако, как только появился ООП, люди начали говорить об IoC в контексте ООП, где приложения занимаются созданием объектов и их взаимоотношениями, помимо потока управления. Такие приложения хотели инвертировать владение созданием объекта (а не потоком управления) и требовали контейнера, который отвечает за создание объекта, жизненный цикл объекта и внедрение зависимостей объектов приложения, тем самым исключая объекты приложения от создания другого конкретного объекта.
В этом смысле DI - это не то же самое, что Io C , поскольку речь идет не о потоке управления, а о разновидности Io * , то есть инверсии владения созданием объекта.
Что не так в моем объяснении DI и IoC?
источник
IoC aka Inversion of Control - элемент управления созданием экземпляров, выполняемый контейнером Spring. Элемент управления созданием и созданием объектов заботится контейнером. Контейнер создает объекты и внедряет их в наше приложение.
источник