dependency-injection управления - Инверсия контроля против инъекции зависимостей




принцип инверсии (16)

Согласно статье, написанной Мартином Фаулером , инверсия управления - это принцип, в котором управляющий поток программы инвертируется: вместо программиста, контролирующего поток программы, внешние источники (каркас, службы и другие компоненты) берут на себя управление Это. Это похоже на то, что мы подключаем что-то еще. Он упомянул пример EJB 2.0:

Например, интерфейс Session Bean определяет ejbRemove, ejbPassivate (хранится во вторичном хранилище) и ejbActivate (восстанавливается из пассивного состояния). Вы не можете контролировать, когда вызываются эти методы, только то, что они делают. Контейнер звонит нам, мы его не называем.

Это приводит к различию между каркасом и библиотекой:

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

Я думаю, точка зрения, что DI является IOC, означает, что зависимость объекта инвертирована: вместо этого он контролирует свои собственные зависимости, жизненный цикл ... что-то еще делает это для вас. Но, как вы рассказали мне о DI руками, DI не обязательно IOC. У нас все еще есть DI и нет МОК.

Однако в этой статье (из pococapsule, другой Framework IOC для C / C ++), это предполагает, что из-за IOC и DI контейнеры IOC и рамки DI намного превосходят J2EE, поскольку J2EE смешивает код структуры с компонентами , тем самым не делая его обычным старым Java / C ++ Object (POJO / POCO).

Инверсия контрольных контейнеров, отличных от шаблона инъекции зависимостей (ссылка на архив)

Дополнительное чтение, чтобы понять, в чем проблема со старой платформой разработки на основе компонентов, которая приводит ко второму документу выше: зачем и что из инверсии управления (ссылка на архив)

Мой вопрос : что такое IOC и DI? Я сбит с толку. Основанный на pococapsule, IOC является чем-то более значительным, чем просто инвертирует контроль между объектами или программистами и фреймворками.


Answers

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

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

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


1) DI - Child-> obj зависит от parent-obj. Важен глагол. 2) IOC - 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


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

DI (Injection Dependency) : Способ инъекции свойств объекту называется инъекцией зависимостей.

We have three types of Dependency injection
    1)  Constructor Injection
    2)  Setter/Getter Injection
    3)  Interface Injection

Весна будет поддерживать только инжекцию конструктора и инъекцию Setter / Getter.


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();
}

При инъекции зависимостей инжекторы зависимостей будут заботиться о создании объектов

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

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

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

Что такое инъекция зависимости?

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

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


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

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

   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.

Dzone.com и прочитать полную статью DI


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

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

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

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

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

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


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

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


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

Термин «инверсия управления» (IoC) первоначально означал любой тип программирования, где общая структура или время выполнения контролировали поток программы

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

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

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


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

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

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

    1). Впрыск конструктора
    2). Ввод установки
    3). Инъекция интерфейса


source

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

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

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

  • Впрыск сеттера
    • Сеттер-основанный DI реализуется путем вызова методов setter в бобах пользователя после вызова конструктора без аргумента или статического заводского метода без аргументов для создания экземпляра их компонента.
  • Инъекция конструктора
    • Диск конструктора основан на вызове конструктора с несколькими аргументами, каждый из которых представляет собой соавтор. Используя это, мы можем проверить, что введенные компоненты не являются нулевыми и не работают быстро (время компиляции), поэтому при запуске самого приложения мы получаем NullPointerException: bean does not exist . Инъекция конструктора - лучшая практика для инъекций зависимостей.

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

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

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

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

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

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

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

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

Injection Dependency предполагает, что вместо зависимых классов (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 и найдет список Typos, который он покажет пользователю.

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

Чтобы обеспечить поддержку для большего количества языков, нам нужно иметь больше 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.

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


// 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.


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

Предположим, мы создаем приложение, которое содержит функцию отправки сообщений подтверждения 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. Поэтому нам нужно внедрить инъекцию зависимостей .

Чтобы достичь этого, нам необходимо реализовать изменение для нашего конструктора классов (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!");
    }
}

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

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

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

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

        Console.ReadLine();
    }
}

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

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

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

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

source



Я написал разницу на моем [блоге]: http://dotnet-stuff.com/tutorials/dependency-injection/dependency-inversion-principle-dependency-injection-and-inversion-of-control-dip-ioc-and -di «нажмите здесь для получения обновлений», что мы можем организовать Inversion of Control, принцип инверсии зависимостей и инжекцию зависимостей. Короче говоря, мы можем сказать,

В начало - принцип инверсии зависимостей, который является способом разработки программного обеспечения. Он не говорит, как сделать независимый модуль. Инверсия управления (IoC) обеспечивает способ применения принципа DPI. Но IoC не дает нам конкретной реализации. Он дает некоторые методы, чтобы мы могли инвертировать элемент управления. Если мы хотим инвертировать управление с помощью инверсии привязки или создания зависимостей, тогда мы можем достичь этого, внедряя инъекцию зависимостей (DI).





dependency-injection inversion-of-control