Что такое инверсия контроля?

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

  1. что это?
  2. какие проблемы он решает?
  3. когда это уместно, а когда нет?

30 ответов


инверсия шаблонов Control (IoC) и Dependency Injection (DI) - это удаление зависимостей из вашего кода.

например, скажите, что ваше приложение имеет компонент текстового редактора, и вы хотите предоставить проверку орфографии. Стандартный код будет выглядеть примерно так:

public class TextEditor {

    private SpellChecker checker;

    public TextEditor() {
        this.checker = new SpellChecker();
    }
}

что мы сделали здесь создает зависимость между TextEditor и SpellChecker. В сценарии МОК мы бы вместо этого сделали что-то вроде это:

public class TextEditor {

    private IocSpellChecker checker;

    public TextEditor(IocSpellChecker checker) {
        this.checker = checker;
    }
}

в первом примере кода мы создаем экземпляр SpellChecker (this.checker = new SpellChecker();), что означает TextEditor класс напрямую зависит от SpellChecker класса.

во втором примере кода мы создаем абстракцию, имея SpellChecker класс зависимостей в TextEditor подпись конструктора (не инициализирует зависимость в классе). Это позволяет нам вызвать зависимость, а затем передать ее классу TextEditor следующим образом:

SpellChecker sc = new SpellChecker; // dependency
TextEditor textEditor = new TextEditor(sc);

теперь клиент создание TextEditor класс имеет контроль над SpellChecker реализация для использования, потому что мы вводим зависимость к TextEditor подпись.

это просто простой пример, есть хорошая серия статей Симоне Бусоли, что объясняет это более подробно.


инверсия управления-это то, что вы получаете при обратных вызовах вашей программы, например, как программа gui.

например, в меню старой школы у вас может быть:

print "enter your name"
read name
print "enter your address"
read address
etc...
store in database

тем самым контролируя поток взаимодействия с пользователем.

в программе GUI или somesuch, вместо этого мы говорим:

when the user types in field a, store it in NAME
when the user types in field b, store it in ADDRESS
when the user clicks the save button, call StoreInDatabase

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

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


Что такое инверсия управления?

Если вы выполните эти простые два шага, вы сделали инверсию управления:

  1. отдельные что - to-do часть от , когда-to-do часть.
  2. обеспечить , когда часть знает как мало о что часть; и наоборот.

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

--

на инверсия часть инверсии управления (IoC) - это запутанная вещь; потому что инверсия относительный термин. Лучший способ понять МОК-забыть об этом слове!

--

примеры

  • Обработка Событий. Обработчики событий (в части) -- просветительские мероприятия (когда в часть)
  • интерфейсы. Компонент клиента (если в части) - компонент реализация интерфейса (в части)
  • xUnit fixure. Setup and TearDown (what-to-do part) -- xUnit Framework вызывает Setup в начале и TearDown в конце (когда-to-do part)
  • Шаблонный метод шаблон проектирования. шаблон метода, когда в часть ... примитивный подкласс реализации в часть
  • методы контейнера DLL в COM. DllMain, DllCanUnload и т. д. (Что делать) -- COM / OS (когда в часть)

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

Без МОК: у тебя есть ноутбук компьютер и вы случайно разбили экран. И черт возьми, вы найдете ту же модель экрана ноутбука нигде на рынке. Значит, ты застрял.

С МОК: у тебя есть рабочий стол компьютер и вы случайно разбили экран. Вы обнаружите, что вы можете просто захватить практически любой настольный монитор с рынка, и он работает хорошо с вашего рабочего стола.

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


инверсия управления (или МОК), о получив свободу (вы выходите замуж, вы потеряли свободу, и вас контролируют. Вы развелись, вы только что осуществили инверсию контроля. Это то, что мы называли "разобщенным". Хорошая компьютерная система отбивает охоту к очень близким отношениям.) гибкость (кухня в вашем офисе служит только чистой водопроводной водой, это ваш единственный выбор, когда вы хотите пить. Ваш босс реализовал инверсию управления установка новой кофемашины. Теперь вы получаете гибкость выбора либо водопроводной воды, либо кофе.) и меньше зависимость (у вашего партнера есть работа, у вас нет работы, вы финансово зависите от своего партнера, поэтому вас контролируют. Вы нашли работу, вы внедрили инверсию контроля. Хорошая компьютерная система поощряет зависимость.)

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

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

с вышеуказанными идеями в разуме. Мы все еще пропускаем ключевую часть МОК. В сценарии IoC потребитель программного обеспечения / объекта представляет собой сложную структуру. Это означает, что созданный вами код вызывается не вами. Теперь давайте объясним, почему этот способ лучше работает для веб-приложения.

предположим, что ваш код-это группа работников. Им нужно построить машину. Эти работники нуждаются в месте и инструментах (программной базе) для сборки автомобиля. А традиционный программное обеспечение framework будет как гараж со многими инструментами. Поэтому рабочие должны сами составить план и использовать инструменты для сборки автомобиля. Строительство автомобиля-нелегкое дело, рабочим будет очень сложно правильно планировать и сотрудничать. А современные рамки программного обеспечения будут как современная фабрика автомобиля со всеми объектами и менеджерами на месте. Рабочие не должны составлять никаких планов, менеджеры (часть рамок, они самые умные люди и сделали самый сложный план) поможет координировать, чтобы работники знали, когда делать свою работу (фреймворк вызывает ваш код). Работники просто должны быть достаточно гибкими, чтобы использовать любые инструменты, которые менеджеры дают им (используя инъекцию зависимостей).

хотя работники дают контроль над управлением проектом на верхнем уровне менеджерам (рамки). Но это хорошо, что некоторые профессионалы помогают. Это концепция МОК, которая действительно исходит.

Современный Веб приложения с архитектурой MVC зависят от платформы для маршрутизации URL и размещения контроллеров для вызова платформы.

инъекция зависимостей и инверсия управления связаны. Инъекция зависимостей находится в микро уровень и инверсия управления находится на макрос


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

плюсы:

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

плюсы:

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

лично я вижу сильные стороны МОК, и мне они очень нравятся, но я, как правило, избегаю МОК, когда это возможно, потому что это превращает ваше программное обеспечение в коллекцию классов, которые больше не составляют "реальную" программу, а просто что-то, что должно быть собрано с помощью конфигурации XML или метаданных аннотаций и без него разваливается (и разваливается).


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

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

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

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


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

Как в этом примере с TextEditor: если у вас есть только один SpellChecker, может быть, на самом деле не нужно использовать IoC ? Если только вам не нужно писать модульные тесты или что-то в этом роде ...

в любом случае: будьте разумными. Шаблон дизайнахорошей практикой но не Библия, чтобы проповедовать. Не вставляйте его повсюду.


предположим, что вы объект. И вы идете в ресторан:

Без МОК: вы просите "яблоко", и вам всегда подают яблоко, когда вы просите больше.

С МОК: вы можете попросить "фрукты". Вы можете получить различные фрукты каждый раз, когда вам подают. например, яблоко, апельсин или арбуз.

таким образом, очевидно, МОК предпочтительнее, когда вам нравятся сорта.


IoC / DI для меня выталкивает зависимости от вызывающих объектов. Очень просто.

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


  1. инверсия управления-это шаблон, используемый для развязки компонентов и слоев в системе. Шаблон реализуется путем введения зависимостей в компонент при его построении. Эти зависимости обычно предоставляются в качестве интерфейсов для дальнейшей развязки и поддержки тестируемости. Контейнеры IoC / DI, такие как Castle Windsor, Unity, являются инструментами (библиотеками), которые могут использоваться для предоставления IoC. Эти инструменты обеспечивают расширенные функции выше и за пределами simple управление зависимостями, включая время жизни, AOP / Перехват, политику и т. д.

  2. a. Уменьшает ответственность компонента за управление зависимостями.
    b. Предоставляет возможность замены реализаций зависимостей в различных средах.
    c. Позволяет компоненту тестироваться путем насмешки над зависимостями.
    d. Обеспечивает механизм совместного использования ресурсов в приложении.

  3. a. Критический при выполнении разработка на основе тестов. Без МОК это может быть трудно проверить, потому что тестируемые компоненты сильно связаны с остальной частью системы.
    b. Критично при разработке модульных систем. Модульная система-это система, компоненты которой могут быть заменены без необходимости перекомпиляции.
    c. Критический, если есть много сквозных проблем, которые необходимо решить, частично в корпоративном приложении.


For quick understanding just read examples*

инъекция зависимостей (DI):
Инъекция зависимостей обычно означает передача объекта, от которого зависит метод, в качестве параметра к методу, а не метод создания зависимого объекта.
на практике это означает, что метод не зависит непосредственно от конкретной реализации; любая реализация, которая соответствует требования могут быть переданы в качестве параметра.

С помощью этих объектов сообщите их зависимости. И весна делает его доступным.
это приводит к разработке слабо связанных приложений.

Quick Example:EMPLOYEE OBJECT WHEN CREATED,
              IT WILL AUTOMATICALLY CREATE ADDRESS OBJECT
   (if address is defines as dependency by Employee object)

инверсия контейнера управления(IoC):
Это общая характеристика основ, МОК управляет объектами java
– от создания экземпляра до разрушения через его BeanFactory.
-компоненты Java, которые установленный контейнер IOC называют фасоль, и контейнер IoC управляет областью действия компонента, событиями жизненного цикла и любыми функциями AOP для которого он был настроен и закодированы.

QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it.

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

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

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

подробное объяснение


отвечая только на первую часть. Что это?

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


например, задача№1-создать объект. Без концепции МОК задача№1 должна выполняться программистом.Но с концепцией IOC задача№1 будет выполняться контейнером.

вкратце управление получает перевернутым от программиста к контейнеру. Итак, это называется инверсией контроля.

Я нашел один хороший пример здесь.


Я согласен с NilObject, но я хотел бы добавить к этому:

Если вы обнаружите, что копируете весь метод и меняете только небольшую часть кода, Вы можете рассмотреть возможность его решения с инверсией управления

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


кажется, что самая запутанная вещь о" МОК " аббревиатура и имя, для которого он стоит, что это слишком гламурное имя-почти шумовое имя.

действительно ли нам нужно имя, чтобы описать разницу между процедурным и событийным программированием? Хорошо, если нам нужно, но нужно ли нам выбирать новое имя" больше, чем жизнь", которое смущает больше, чем решает?


давайте скажем, что мы делаем некоторые встречи в каком-то отеле.

много людей, много графинов воды, много пластиковых чашек.

через час или что-то у нас есть пол, покрытый пластиковыми стаканами и водой.

пусть инвертировать управление.

та же встреча в том же месте, но вместо пластиковых стаканчиков у нас есть официант с одной стеклянной чашкой (Синглтон)

и она все время предлагает гостям выпить.

когда кто-то хочет выпить, она получает от официанта стакан, выпить и вернуть его обратно официанту.

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

и это именно то, что делает Spring (другой контейнер IoC, например: Guice). Вместо let to application создайте то, что ему нужно, используя новое ключевое слово (принимая пластиковый стаканчик), весенний контейнер МОК все время предлагают применять один и тот же экземпляр(синглтон) необходимого объекта (стакан воды).

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

членам собрания понадобится стакан воды, но не кусок пирога.

пример:

public class MeetingMember {

    private GlassOfWater glassOfWater;

    ...

    public void setGlassOfWater(GlassOfWater glassOfWater){
        this.glassOfWater = glassOfWater;
    }
    //your glassOfWater object initialized and ready to use...
    //spring IoC  called setGlassOfWater method itself in order to
    //offer to meetingMember glassOfWater instance

}

полезное ссылки:-


IoC-это инвертирование отношений между вашим кодом и сторонним кодом (библиотека/фреймворк):

  • в нормальном развитии s/w вы пишете main () метод и вызов методов" библиотека". вы в управление :)
  • В МОК "рамки" управления main () и вызовов методов. The рамки находится в управлении :(

DI (инъекция зависимостей) - о том, как протекает управление в приложении. Традиционное настольное приложение имело поток управления от вашего приложения (метод main ()) к другим вызовам метода библиотеки, но с di поток управления инвертирован, что фреймворк заботится о запуске вашего приложения, инициализации его и вызове ваших методов, когда это необходимо.

В конце концов вы всегда выиграете :)


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

классический код (без инъекции зависимостей)

вот как код, не использующий DI, будет примерно работать:

  • приложение нуждается в Foo (например, контроллер), так что:
  • приложение создает Foo
  • вызовы приложений Foo
    • Foo нуждается в баре (например, сервис), поэтому:
    • Foo создает Бар
    • Foo вызывает бар
      • бар нуждается в Bim (сервис, репозиторий,...), так что:
      • бар создает Bim
      • бар что-то делает

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

вот как код с помощью DI будет примерно работать:

  • приложение нуждается в Foo, который нуждается в баре, который нуждается в Bim, так что:
  • приложение создает Bim
  • приложение создает бар и дает ему Bim
  • приложение создает Foo и дает ему Bar
  • вызовы приложений Foo
    • Foo вызывает бар
      • бар что-то делает

управление зависимостями инвертируется один в один вызов.

какие проблемы она решить?

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

Ex: предположим, ваше приложение хранит загруженный пользователем файл на Google Диске, с DI ваш код контроллера может выглядеть так:

class SomeController
{
    private $storage;

    function __construct(StorageServiceInterface $storage)
    {
        $this->storage = $storage;
    }

    public function myFunction () 
    {
        return $this->storage->getFile($fileName);
    }
}

class GoogleDriveService implements StorageServiceInterface
{
    public function authenticate($user) {}
    public function putFile($file) {}
    public function getFile($file) {}
}

когда ваши требования изменятся, скажем, вместо GoogleDrive вас попросят использовать Dropbox. Вам нужно только написать реализацию dropbox для StorageServiceInterface. У вас нет никаких изменений в контроллере, пока реализация Dropbox придерживается StorageServiceInterface.

во время тестирования вы можете создать макет для StorageServiceInterface с фиктивной реализацией, где все методы возвращают null(или любое предопределенное значение в соответствии с вашим требованием тестирования).

вместо этого, если у вас был класс контроллера для создания хранилища объект с new ключевое слово вроде этого:

class SomeController
{
    private $storage;

    function __construct()
    {
        $this->storage = new GoogleDriveService();
    }

    public function myFunction () 
    {
        return $this->storage->getFile($fileName);
    }
}

когда вы хотите изменить с реализацией Dropbox вы должны заменить все строки, где new объект GoogleDriveService построен и использует DropboxService. Кроме того, при тестировании класса SomeController конструктор всегда ожидает, что класс GoogleDriveService и фактические методы этого класса будут запущены.

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


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

в терминах программирования она передала функцию обратного вызова getProductList() к функции, которую вы выполняете doShopping();

оно позволяет потребителю функции определить некоторые части его делая его более гибким.


очень простое письменное объяснение можно найти здесь

http://binstock.blogspot.in/2008/01/excellent-explanation-of-dependency.html

Он говорит:

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


программирования, говоря

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

например, предположим, что у нас есть два класса:собака и кошки. Оба имеют одинаковые качества / состояния: возраст, размер, вес. Поэтому вместо создания класса сервиса под названием DogService и CatService, Я могу создать один под названием AnimalService что позволяет использовать собаку и кошку, только если они используют интерфейс IAnimal.

однако, прагматически говоря, у него есть некоторые задом наперед.

a)большинство разработчиков не знают, как его использовать. Например, я могу создать класс клиент и Я могу создавать автоматически (С помощью инструментов IDE) интерфейс называется ICustomer. Таким образом, не редко можно найти папку, заполненную классами и интерфейсами, независимо от того, будут ли интерфейсы использоваться повторно или нет. Это называется вздутие живота. Некоторые люди могут утверждать, что "может быть, в будущем мы могли бы использовать его". :-|

б) он имеет некоторые limitings. Например, давайте поговорим о случае собака и кошки и я хочу добавить новую услугу (функцию) только для собак. Допустим, я хочу вычислить количество дней, которые я нужно дрессировать собаку (trainDays()), для кошки это бесполезно, кошки не могут быть обучены (я шучу).

b.1) Если я добавлю trainDays() к сервису AnimalService тогда он также работает с кошками, и он вообще недействителен.

b.2) я могу добавить условие в trainDays() где он оценивает, какой класс используется. Но это полностью сломает МОК.

b.3) я могу создать новый класс обслуживания под названием DogService только для новых функциональность. Но, это увеличит ремонтопригодность кода, потому что у нас будет два класса обслуживания (с аналогичной функциональностью) для собака и это плохо.


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

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

для тех, кто интересуется более подробно об инверсии управления документ был опубликован изложением более полной картины инверсии управления как шаблон (OfficeFloor: использование моделей управления в целях повышения эффективности разработки программного обеспечения http://doi.acm.org/10.1145/2739011.2739013 с бесплатную копию можно скачать с http://www.officefloor.net/mission.html)

Что идентифицируется следующая зависимость:

инверсия управления (для методов) = зависимость (состояние) инъекция + инъекция продолжения + инъекция нити


Мне нравится это объяснение: http://joelabrahamsson.com/inversion-of-control-an-introduction-with-examples-in-net/

Это начать просто и показывает примеры кода, а также.

enter image description here

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

разве недостаточно, что X знает, что он использует что-то, что имеет поведение, методы, свойства и т. д., Не зная, кто на самом деле реализует поведение?

извлекая абстрактное определение поведения, используемого X в Y, проиллюстрированное как I ниже, и позволяя потребителю X использовать экземпляр этого вместо Y, он может продолжать делать то, что он делает, не зная особенностей Y.

enter image description here

на иллюстрации выше y реализует I и X использует экземпляр I. В то время как это вполне возможно, что X все еще использует Y интересно то, что X этого не знает. Он просто знает, что использует то, что реализует I.

прочитайте статью для получения дополнительной информации и описания преимуществ, таких как:

  • X больше не зависит от Y
  • более гибкий, реализация может быть решена во время выполнения
  • изоляция блока кода, более легкое испытание

...


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

инверсия управления (IoC) была построена по очень простому принципу под названием Принцип Голливуда. И он говорит, что

Не звоните нам, мы позвоним вам

Это означает, что не идти в Голливуд, чтобы выполнить свою мечту, а если вы достойны, тогда Голливуд найдет вас и сделает вашу мечту реальностью. Довольно сильно перевернуто, да?

теперь, когда мы обсуждаем принцип МОК, мы обычно забываем о Голливуде. Для МОК должно быть три элемента, Голливуд, вы и задача, как выполнить свою мечту.

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

реальная жизнь пример будет приведен здесь. Предположим, вы хотите разработать веб-приложения. Итак, вы создаете фреймворк, который будет обрабатывать все общие вещи, которые веб-приложение должно обрабатывать, такие как обработка http-запроса, создание меню приложения, обслуживание страниц, управление куки, запуск событий и т. д.

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

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

Laravel и EJB являются примерами такого интегрированные системы.

ссылки:

https://martinfowler.com/bliki/InversionOfControl.html

https://en.wikipedia.org/wiki/Inversion_of_control


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


  1. Итак, номер 1 выше. что такое инверсия управления?

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

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

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

public class MessagePublisher<RECORD,MESSAGE>
{
    public MessagePublisher(IMapper<RECORD,MESSAGE> mapper,IRemoteEndpoint endPointToSendTo)
    {
      //setup
    }
}

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

О да, есть проблемы с тестируемостью, но они вторичны по отношению к преимуществам IoC/DI.

Я определенно люблю IoC / DI.

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


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


для понимания концепции инверсия управления (IoC) или принцип инверсии зависимостей (DIP) включает в себя два вида деятельности: абстракцию и инверсию. Инъекция зависимостей (DI) является лишь одним из немногих методов инверсии.

подробнее об этом вы можете прочитать в моем блоге здесь

  1. что это?

Это практика, когда вы позволяете фактическому поведению исходить из-за границы (класс в объектно-ориентированном Программирование.) Граничная сущность знает только абстракцию (e.G интерфейс, абстрактный класс, делегат в объектно-ориентированном программировании).

  1. какие проблемы он решает?

с точки зрения программирования, МОК пытается решить монолитный код, сделав его модульным, отделив различные его части и сделав его тестируемым.

  1. когда это уместно, а когда нет?

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


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

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

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