Инверсия Контроля против Инъекции Зависимостей

525

Согласно статье, написанной Мартином Фаулером , инверсия управления является принципом, в котором поток управления программы инвертируется: вместо программиста, управляющего потоком программы, внешние источники (инфраструктура, службы, другие компоненты) принимают на себя управление Это. Как будто мы подключаем что-то к чему-то другому. Он привел пример с 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 является чем-то более значительным, чем просто инверсия управления между объектами или программистами и средами.

Амуму
источник
2
Вот хорошая запись на эту тему, IoC против DI (Dependency Inject) против SL (Service Locator): tinyurl.com/kk4be58 - Извлечение из URL: IoC против DI (Dependency Injection)? IoC - это общая концепция, в которой управление потоком инвертируется из клиентского кода в платформу, которая «делает что-то для клиента». SL (Service Locator) и DI (Dependency Injection) - это две схемы проектирования, основанные на IoC.
Swab.Jat
Чтобы добавить мои два цента, если кому-то интересно, как внедрение зависимости может быть полезным в теме кафе, я написал статью об этом здесь: digigene.com/design-patterns/dependency-injection-coffeeshop
Али Нем
3
достойная статья для начинающих asimplify.com/dependency-injection-inversion-control
Хаваджа Асим
Инверсия зависимостей: зависит от абстракций, а не от конкреций. Инверсия управления: главное против абстракции и то, как главное - это клей систем. Вот несколько хороших постов, рассказывающих об этом: coderstower.com/2019/03/26/… coderstower.com/2019/04/02/… coderstower.com/2019/04/09/…
Даниэль Андрес Пелаес Лопес
читать об этом глубоко, это очистит все martinfowler.com/articles/...
Дэшман

Ответы:

644

IoC - это общий термин, означающий, что приложение не вызывает методы в платформе, а платформа вызывает реализации, предоставляемые приложением.

DI - это форма IoC, где реализации передаются в объект через поиск конструкторов / установщиков / служб, от которого объект будет «зависеть» для правильного поведения.

Например, IoC без использования DI будет шаблоном шаблона, потому что реализация может быть изменена только с помощью подклассов.

DI Frameworks предназначены для использования DI и могут определять интерфейсы (или аннотации в Java), чтобы упростить передачу реализаций.

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

Смотрите также эту статью Мартина Фаулера .

Гарретт Холл
источник
2
Спасибо за ответ. Но другой документ предполагает, что с IOC контейнеры IOC намного превосходят EJB, в то время как Мартин Фаулер предполагает, что EJB является типичным примером IOC.
Amumu
5
Управление EJB действительно типичный пример IoC. Это видно из того факта, что жизненным циклом EJB управляет контейнер, а не программист. Программист не создает и не уничтожает экземпляр EJB, поскольку элемент управления делегирован на сервер . Такова концепция IoC: внешний код контролирует, когда вызывается ваш код, что обычно противоположно тому, что он делал большую часть времени.
Brandizzi
2
IoC - это общий термин, означающий, что приложение не вызывает методы в платформе, а платформа вызывает реализации, предоставляемые приложением. Можете ли вы объяснить это больше об этом?
Имад Алазани
21
Ака голливудский принцип , «не звоните нам, мы вам позвоним». Оставляет вызов до структуры, а не приложения.
Гарретт Холл
@ImadAlazani, вам лучше прочитать статью, которую Гарретт приложил, которая представляет собой подробное обсуждение преобразования элемента управления из кода приложения в платформу.
MengT
210

Короче говоря, IoC - это гораздо более широкий термин, который включает, но не ограничивается, DI

Термин Inversion of Control (IoC) первоначально означал любой стиль программирования, когда общая среда или среда выполнения контролировали ход программы.

До того, как у DI появилось имя, люди начали ссылаться на структуры, которые управляют зависимостями, как инверсию контейнеров управления, и вскоре значение IoC постепенно сместилось к этому конкретному значению: инверсия контроля над зависимостями.

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

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

Томаш Яскуля
источник
1
Похоже, IoC - это просто еще один термин для принципа инверсии зависимости, не так ли?
Тодд Вэнс
@ToddVance - Да, я думаю, что IoC и DIP - это одно и то же. DIP и DI - это не одно и то же. IoC может быть выполнен без DI, но DI не может быть выполнен без IoC.
Eljay
2
@ToddVance - Нет, DIP и IoC не являются синонимами и не связаны между собой.
Цмит
3
Ха, вот почему я здесь в этой теме ... "Инверсия контроля против инъекции зависимостей"
Тодд Вэнс
50

введите описание изображения здесь
источник

IoC ( я nversion о е C ontrol): - Это общий термин , и реализуется несколькими способами (события, делегаты и т.д.).

DI ( D ependency I njection): - DI является подтипом IoC и реализуется путем инъекции конструктора, инъекции сеттера или инъекции интерфейса .

Но Spring поддерживает только следующие два типа:

  • Сеттер Инъекция
    • DI на основе сеттера реализуется путем вызова методов сеттера на бинах пользователя после вызова конструктора без аргументов или статического метода фабрики без аргументов для создания экземпляра его бина.
  • Конструктор Инъекция
    • DI на основе конструктора реализуется путем вызова конструктора с несколькими аргументами, каждый из которых представляет коллаборатора. Используя это, мы можем проверить, что внедренные bean-компоненты не равны null и не работают быстро (дают сбой во время компиляции, а не во время выполнения), поэтому при запуске самого приложения мы получаем NullPointerException: bean does not exist. Внедрение в конструктор - это лучшая практика для внедрения зависимостей.
Premraj
источник
1
неверно утверждать, что Spring не поддерживает внедрение свойств. Оно делает. И это плохая практика, я согласен.
kekko12
Spring @Autowired - аннотация, на мой взгляд, способ внедрения свойств
Sajith
49

DI является подмножеством IoC

  • IoC означает, что объекты не создают другие объекты, на которые они полагаются при выполнении своей работы. Вместо этого они получают нужные им объекты из внешнего сервиса (например, файла XML или отдельного сервиса приложения). Я использую две реализации IoC: DI и ServiceLocator.
  • DI означает, что принцип IoC получения зависимого объекта выполняется без использования конкретных объектов, но абстракций (интерфейсов). Это делает все компоненты цепочки тестируемыми, потому что компонент более высокого уровня не зависит от компонента более низкого уровня, только от интерфейса. Максы реализуют эти интерфейсы.

Вот некоторые другие методы для достижения IoC .

Лапенков Владимир
источник
Я бы не сказал, что IoC означает не создавать объекты. Когда вы вызываете не метод класса напрямую, а метод интерфейса - это инверсия управления (так как в этом случае вызывающая сторона не зависит от вызывающего кода) и она вообще не связана с созданием объекта. Еще одним примером IoC являются мероприятия и делегаты
Евгений Горбовой
20

IOC (Inversion Of Control) : Предоставление контроля контейнеру для получения экземпляра объекта называется Inversion of Control. Это означает, что вместо того, чтобы создавать объект с помощью оператора new, пусть контейнер сделает это за вас.

DI (Dependency Injection) : способ внедрения свойств в объект называется Dependency Injection .

У нас есть три типа внедрения зависимостей :

  1. Конструктор Инъекция
  2. Сеттер / Геттер Инъекция
  3. Интерфейс впрыска

Spring поддерживает только Constructor Injection и Setter / Getter Injection .

kn3l
источник
19

Поскольку все ответы подчеркивают теорию, я хотел бы продемонстрировать на примере первого подхода:

Предположим, мы создаем приложение, которое содержит функцию отправки SMS-сообщений с подтверждением после отправки заказа. У нас будет два класса, один отвечает за отправку SMS (SMSService), а другой отвечает за сбор пользовательских данных (UIHandler), наш код будет выглядеть следующим образом:

public class SMSService
{
    public void SendSMS(string mobileNumber, string body)
    {
        SendSMSUsingGateway(mobileNumber, body);
    }

    private void SendSMSUsingGateway(string mobileNumber, string body)
    {
        /*implementation for sending SMS using gateway*/
    }
}

public class UIHandler
{
    public void SendConfirmationMsg(string mobileNumber)
    {
        SMSService _SMSService = new SMSService();
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

Вышеприведенная реализация не является неправильной, но есть несколько проблем:
-) Предположим, что в среде разработки вы хотите сохранить SMS, отправленные в текстовый файл вместо использования шлюза SMS, чтобы достичь этого; мы закончим тем, что изменили конкретную реализацию (SMSService) на другую реализацию, мы теряем гибкость и вынуждены переписывать код в этом случае.
-) Мы закончим смешивать обязанности классов, наш (UIHandler) никогда не должен знать о конкретной реализации (SMSService), это должно быть сделано вне классов с использованием «Интерфейсов». Когда это будет реализовано, это даст нам возможность изменить поведение системы путем замены (SMSService), используемого с другим фиктивным сервисом, который реализует тот же интерфейс, этот сервис будет сохранять SMS-сообщения в текстовом файле вместо отправки на mobileNumber.

Чтобы исправить вышеуказанные проблемы, мы используем интерфейсы, которые будут реализованы нашим (SMSService) и новым (MockSMSService), в основном новый интерфейс (ISMSService) будет демонстрировать такое же поведение обеих служб, как и код ниже:

public interface ISMSService
{
    void SendSMS(string phoneNumber, string body);
}

Затем мы изменим нашу (SMSService) реализацию для реализации интерфейса (ISMSService):

public class SMSService : ISMSService
{
    public void SendSMS(string mobileNumber, string body)
    {
        SendSMSUsingGateway(mobileNumber, body);
    }

    private void SendSMSUsingGateway(string mobileNumber, string body)
    {
        /*implementation for sending SMS using gateway*/
        Console.WriteLine("Sending SMS using gateway to mobile: 
        {0}. SMS body: {1}", mobileNumber, body);
    }
}

Теперь мы сможем создать новый макетный сервис (MockSMSService) с совершенно другой реализацией, используя тот же интерфейс:

public class MockSMSService :ISMSService
{
    public void SendSMS(string phoneNumber, string body)
    {
        SaveSMSToFile(phoneNumber,body);
    }

    private void SaveSMSToFile(string mobileNumber, string body)
    {
        /*implementation for saving SMS to a file*/
        Console.WriteLine("Mocking SMS using file to mobile: 
        {0}. SMS body: {1}", mobileNumber, body);
    }
}

На этом этапе мы можем изменить код в (UIHandler), чтобы легко использовать конкретную реализацию службы (MockSMSService), как показано ниже:

public class UIHandler
{
    public void SendConfirmationMsg(string mobileNumber)
    {
        ISMSService _SMSService = new MockSMSService();
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

Мы достигли большой гибкости и реализовали разделение проблем в нашем коде, но все же нам нужно внести изменения в кодовую базу для переключения между двумя службами SMS. Поэтому нам нужно внедрить Dependency Injection .

Чтобы достичь этого, нам нужно реализовать изменение в нашем (UIHandler) конструкторе класса, чтобы передать через него зависимость, тем самым код, который использует (UIHandler), может определить, какую конкретную реализацию (ISMSService) использовать:

public class UIHandler
{
    private readonly ISMSService _SMSService;

    public UIHandler(ISMSService SMSService)
    {
        _SMSService = SMSService;
    }

    public void SendConfirmationMsg(string mobileNumber)
    {
        _SMSService.SendSMS(mobileNumber, "Your order has been shipped successfully!");
    }
}

Теперь форма UI, которая будет общаться с классом (UIHandler), отвечает за передачу используемой реализации интерфейса (ISMSService). Это означает, что мы инвертировали элемент управления (UIHandler) больше не отвечает за решение, какую реализацию использовать, вызывающий код делает. Мы внедрили принцип инверсии управления, одним из которых является DI.

Код формы пользовательского интерфейса будет таким, как показано ниже:

class Program
{
    static void Main(string[] args)
    {
        ISMSService _SMSService = new MockSMSService(); // dependency

        UIHandler _UIHandler = new UIHandler(_SMSService);
        _UIHandler.SendConfirmationMsg("96279544480");

        Console.ReadLine();
    }
}
JerryGoyal
источник
Отличное объяснение
ZiviMagic
5

Но весенняя документация говорит, что они одинаковы.

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-introduction

В первой строке « IoC также известен как внедрение зависимостей (DI) ».

user3386493
источник
1
Я думаю, что они пытались решить, что DI - это очень широко используемая разновидность шаблона проектирования IoC, которую почти легко можно назвать IoC, иначе говоря, DI - если в документации нет какой-либо явной ссылки, которая предлагает иное.
ha9u63ar
5
«IoC также известен как инъекция зависимостей (DI)» ... лошадь-перья!
MikeM
5

IoC - Инверсия управления - это общий термин, независимый от языка, он на самом деле не создает объекты, а описывает, в каком режиме создается объект моды.

DI - Dependency Injection - это конкретный термин, в котором мы предоставляем зависимости объекта во время выполнения, используя различные методы внедрения, а именно. Инъекция сеттера, инжектор конструктора или интерфейсная инъекция.

Рахул Гупта
источник
4

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

Существует несколько основных методов реализации инверсии управления. Эти:

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

    1). Конструктор инъекций
    2). Сеттер впрыска
    3). Внедрение интерфейса
Саурабх
источник
4

DI и IOC - это два шаблона проектирования, которые в основном направлены на обеспечение слабой связи между компонентами или просто на способ, которым мы отделяем обычные отношения зависимости между объектами, чтобы объекты не были связаны друг с другом.

Следующими примерами я пытаюсь объяснить обе эти концепции.

Ранее мы пишем такой код

Public MyClass{
 DependentClass dependentObject
 /*
  At somewhere in our code we need to instantiate 
  the object with new operator  inorder to use it or perform some method.
  */ 
  dependentObject= new DependentClass();
  dependentObject.someMethod();
}

С внедрением Dependency, инжектор зависимостей позаботится о создании объектов

Public MyClass{
 /* Dependency injector will instantiate object*/
 DependentClass dependentObject

 /*
  At somewhere in our code we perform some method. 
  The process of  instantiation will be handled by the dependency injector
 */ 

  dependentObject.someMethod();
}

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

IOC - это принцип, в котором управляющий поток программы инвертируется: вместо программиста, управляющего потоком программы , программа управляет потоком, уменьшая накладные расходы для программиста. Процесс, используемый программой для внедрения зависимости, называется DI

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

Также рекомендую прочитать.

Что такое внедрение зависимостей?

Вы также можете проверить один из моих похожих ответов здесь

Разница между инверсией контроля и инъекцией зависимостей

samuelj90
источник
3

Inversion of Control - это общий принцип проектирования архитектуры программного обеспечения, который помогает создавать модульные программные структуры многократного использования, которые просты в обслуживании.

Это принцип разработки, при котором поток управления «принимается» из общей библиотеки или кода многократного использования.

Чтобы понять это лучше, давайте посмотрим, как мы использовали кодирование в наши ранние дни кодирования. В процедурных / традиционных языках бизнес-логика, как правило, контролирует поток приложения и «вызывает» общий или повторно используемый код / ​​функции. Например, в простом консольном приложении мой поток управления контролируется инструкциями моей программы, которые могут включать в себя вызовы некоторых общих повторно используемых функций.

print ("Please enter your name:");
scan (&name);
print ("Please enter your DOB:");
scan (&dob);

//More print and scan statements
<Do Something Interesting>

//Call a Library function to find the age (common code)
print Age

В отличие от этого, с IoC, фреймворки представляют собой повторно используемый код, который «вызывает» бизнес-логику.

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

Хотя код фреймворка не знает о моей бизнес-логике, он все равно будет знать, как вызывать мой код. Это достигается с помощью событий / делегатов, обратных вызовов и т. Д. Здесь управление потоком является «инвертированным».

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

Внедрение зависимостей - это шаблон проектирования, в котором реализован принцип IoC для разрешения зависимостей объектов.

Проще говоря, когда вы пытаетесь написать код, вы будете создавать и использовать разные классы. Один класс (класс A) может использовать другие классы (класс B и / или D). Итак, класс B и D являются зависимостями класса A.

Простая аналогия будет классом автомобилей. Автомобиль может зависеть от других классов, таких как двигатель, шины и многое другое.

Внедрение зависимостей предполагает, что вместо зависимых классов (здесь Class Car), создающих свои зависимости (Class Engine и класс Tire), класс должен быть внедрен с конкретным экземпляром зависимости.

Давайте разберемся с более практичным примером. Учтите, что вы пишете свой собственный TextEditor. Среди прочего, вы можете иметь проверку орфографии, которая предоставляет пользователю возможность проверить опечатки в его тексте. Простая реализация такого кода может быть:

Class TextEditor
{

    //Lot of rocket science to create the Editor goes here

    EnglishSpellChecker objSpellCheck;
    String text;

    public void TextEditor()

    {   

        objSpellCheck = new EnglishSpellChecker();

    }

    public ArrayList <typos> CheckSpellings()
    {

        //return Typos;

    }

}

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

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

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

Здесь мы создали тесно связанный код с «английским» SpellChecker, тесно связанным с нашим классом TextEditor, что означает, что наш класс TextEditor зависит от EnglishSpellChecker или, другими словами, EnglishSpellCheker является зависимостью для TextEditor. Нам нужно удалить эту зависимость. Кроме того, нашему текстовому редактору нужен способ хранить конкретную ссылку любой программы проверки орфографии на основе усмотрения разработчика во время выполнения.

Итак, как мы видели во введении DI, он предлагает вводить класс с его зависимостями. Таким образом, вызывающий код должен нести ответственность за внедрение всех зависимостей в вызываемый класс / код. Таким образом, мы можем реструктурировать наш код как

interface ISpellChecker
{

    Arraylist<typos> CheckSpelling(string Text);

}

Class EnglishSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}



Class FrenchSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}

В нашем примере класс TextEditor должен получить конкретный экземпляр типа ISpellChecker.

Теперь зависимость может быть введена в Constructor, Public Property или метод.

Давайте попробуем изменить наш класс, используя Constructor DI. Измененный класс TextEditor будет выглядеть примерно так:

Class TextEditor

{

    ISpellChecker objSpellChecker;

    string Text;



    public void TextEditor(ISpellChecker objSC)

    {

        objSpellChecker = objSC;

    }



    public ArrayList <typos> CheckSpellings()

    {

        return objSpellChecker.CheckSpelling();

    }

}

Чтобы вызывающий код при создании текстового редактора мог внедрить соответствующий тип SpellChecker в экземпляр TextEditor.

Вы можете прочитать полную статью здесь

Amrit
источник
3

IOC (Inversion Of Control): Предоставление контроля контейнеру для получения экземпляра объекта называется Inversion of Control. Это означает, что вместо того, чтобы создавать объект с помощью оператора new , пусть контейнер сделает это за вас.

DI (Dependency Injection). Передача необходимых параметров (свойств) из XML в объект (в POJO CLASS) называется внедрением Dependency Injection .

Суреш Кумар Мск
источник
2

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

Основные задачи, выполняемые контейнером IoC: создание экземпляра класса приложения. настроить объект. собрать зависимости между объектами.

DI - это процесс предоставления зависимостей объекта во время выполнения с использованием внедрения сеттера или конструктора.

Кунал
источник
2

IOC (Inversion of Control) - это, по сути, концепция шаблона проектирования, заключающаяся в удалении зависимостей и их разделении, чтобы сделать поток нелинейным, и позволить контейнеру / или другому объекту управлять предоставлением зависимостей. Это на самом деле следует голливудскому принципу «Не звоните нам, мы вам позвоним». Итак, подытоживая различия.

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

Внедрение зависимостей: - DI является подтипом IOC и реализуется путем инжекции в конструктор, вложения метода или метода.

Следующая статья описывает это очень аккуратно.

https://www.codeproject.com/Articles/592372/Dependency-Injection-DI-vs-Inversion-of-Control-IO

сверхновая звезда
источник
1

Я думаю, что идея может быть продемонстрирована ясно, не вдаваясь в объектно-ориентированные сорняки, которые, кажется, запутывают идею.

// dependency injection
function doSomething(dependency) {
    // do something with your dependency
}

// in contrast to creating your dependencies yourself
function doSomething() {
    dependency = getDependencySomehow()
}

// inversion of control
application = makeApp(authenticate, handleRequest, sendResponse)
application.run(getRequest())

// in contrast to direct control or a "library" style
application = makeApp()
request = application.getRequest()

if (application.authenticate(request.creds)) {
    response = application.handleRequest(request)
    application.sendResponse(response)
}

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

Рич Ремер
источник
0

Давайте начнем с D SOLID и посмотрим на DI и IoC из книги Скотта Миллета «Профессиональные шаблоны проектирования ASP.NET»:

Принцип обращения зависимостей (DIP)

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

Инъекция зависимостей (DI) и инверсия контроля (IoC)

С DIP тесно связаны принцип DI и принцип IoC. DI - это акт предоставления низкоуровневого или зависимого класса через конструктор, метод или свойство. Используемые вместе с DI, эти зависимые классы могут быть преобразованы в интерфейсы или абстрактные классы, что приведет к слабосвязанным системам, которые легко тестируются и легко изменяются.

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

Millett, C (2010). Профессиональные шаблоны проектирования ASP.NET. Wiley Publishing. 7-8.

GorkemHalulu
источник
0

// ICO, DI, 10 лет назад, вот так:

public class  AuditDAOImpl implements Audit{

    //dependency
    AuditDAO auditDAO = null;
        //Control of the AuditDAO is with AuditDAOImpl because its creating the object
    public AuditDAOImpl () {
        this.auditDAO = new AuditDAO ();
    }
}

Теперь с весны 3,4 или последним, как показано ниже

public class  AuditDAOImpl implements Audit{

    //dependency

     //Now control is shifted to Spring. Container find the object and provide it. 
    @Autowired
    AuditDAO auditDAO = null;

}

В целом элемент управления инвертируется из старой концепции связанного кода в такие среды, как Spring, что делает объект доступным. Так что, насколько я знаю, это IOC и внедрение зависимостей, как вы знаете, когда мы внедряем зависимый объект в другой объект, используя конструктор или сеттеры. Inject в основном означает передачу его в качестве аргумента. Весной у нас есть конфигурация на основе XML и аннотаций, в которой мы определяем объект bean и передаем зависимый объект в стиле Constructor или setter.

Vaibs
источник
0

Я нашел лучший пример на Dzone.com, который действительно помогает понять реальные различия между IOC и DI

«IoC - это когда кто-то еще создает объекты для вас». Таким образом, вместо того, чтобы писать «новое» ключевое слово (например, MyCode c = new MyCode ()) в вашем коде, объект создается кем-то другим. Этот «кто-то еще» обычно называется контейнером IoC. Это означает, что мы передаем rrsponsibility (control) контейнеру, чтобы получить экземпляр объекта, называемый Inversion of Control., Означает, что вместо того, чтобы создавать объект с помощью оператора new, пусть контейнер сделает это за вас.

   DI(Dependency Injection):  Way of injecting properties to an object is 
   called 
  Dependency injection.
   We have three types of Dependency injection
    1)  Constructor Injection
    2)  Setter/Getter Injection
    3)  Interface Injection
   Spring will support only Constructor Injection and Setter/Getter Injection.

Читать статью полностью IOC и Читать статью DI полностью

Сачиндра Н. Пандей
источник
0

1) DI - это Child-> obj, зависит от parent-obj. Глагол зависит важно. 2) МОК - это Child-> obj, выступающий под платформой. где платформой может быть школа, колледж, танцевальный класс. Здесь выполняются действия с различными последствиями под любым поставщиком платформы.

практический пример: `

//DI
child.getSchool();
//IOC
child.perform()// is a stub implemented by dance-school
child.flourish()// is a stub implemented by dance-school/school/

`

-AB

Абхишек
источник
0

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

Внедрение IoC

В объектно-ориентированном программировании есть несколько основных методов для реализации инверсии управления. Эти:

  1. Использование шаблона локатора службы Использование внедрения зависимостей, например, инъекция в конструктор. Инъекция параметров. Инъекция в сеттер. Инъекция интерфейса;
  2. Использование контекстного поиска;
  3. Использование шаблонного метода проектирования шаблона;
  4. Использование шаблона проектирования стратегии

Что касается внедрения зависимости

Внедрение зависимостей - это метод, при котором один объект (или статический метод) предоставляет зависимости другого объекта. Зависимость - это объект, который можно использовать (сервис). Инъекция - это передача зависимости зависимому объекту (клиенту), который будет его использовать.

Hearen
источник
0

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

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

В этом смысле DI - это не то же самое, что Io C , поскольку речь идет не о потоке управления, а о разновидности Io * , то есть инверсии владения созданием объекта.

Что не так в моем объяснении DI и IoC?

Фахим Фарук
источник
0

IoC aka Inversion of Control - элемент управления созданием экземпляров, выполняемый контейнером Spring. Элемент управления созданием и созданием объектов заботится контейнером. Контейнер создает объекты и внедряет их в наше приложение.

Анжу Мохан
источник