Вопрос:

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

oop design-patterns inversion-of-control

437464 просмотра

30 ответа

24646 Репутация автора

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

  1. Что это?
  2. Какую проблему это решает?
  3. Когда это целесообразно использовать, а когда нет?
Автор: Mike Minutillo Источник Размещён: 06.08.2008 03:35

Ответы (30)


64 плюса

9944 Репутация автора

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

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

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

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

Автор: NilObject Размещён: 06.08.2008 04:33

16 плюса

36108 Репутация автора

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

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

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

Автор: Peter Burns Размещён: 06.08.2008 05:20

562 плюса

180524 Репутация автора

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

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

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

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

В программе с графическим интерфейсом или что-то подобное мы говорим:

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

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

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

Автор: Mark Harrison Размещён: 06.08.2008 05:42

1352 плюса

21471 Репутация автора

Решение

Шаблоны Inversion of Control (IoC) и Dependency Injection (DI) предназначены для удаления зависимостей из вашего кода.

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

public class TextEditor {

    private SpellChecker checker;

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

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

public class TextEditor {

    private IocSpellChecker checker;

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

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

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

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

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

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

Автор: urini Размещён: 06.08.2008 07:22

43 плюса

7592 Репутация автора

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

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

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

Автор: Michal Sznajder Размещён: 06.08.2008 10:08

25 плюса

8293 Репутация автора

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

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

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

Автор: Glenn Block Размещён: 19.09.2008 02:27

39 плюса

8915 Репутация автора

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

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

Автор: ferventcoder Размещён: 19.09.2008 02:54

3 плюса

8915 Репутация автора

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

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

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

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

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

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

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

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

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

Автор: ferventcoder Размещён: 19.09.2008 04:59

17 плюса

171 Репутация автора

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

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

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

Автор: gogs Размещён: 27.01.2010 12:15

84 плюса

1681 Репутация автора

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

Плюсы:

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

Минусы:

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

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

Автор: ahe Размещён: 12.02.2010 02:31

395 плюса

6814 Репутация автора

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

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

  1. Раздельное , что -в-делать часть из когда -в-не разлучит.
  2. Убедитесь в том, что , когда часть знает , как мало , насколько это возможно о какой части; и наоборот.

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

-

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

-

Примеры

  • Обработка событий. Обработчики событий (часть «что нужно делать») - «Возникновение событий» (часть «когда нужно делать»)
  • Интерфейсы. Компонентный клиент (часть при выполнении) - реализация интерфейса компонента (часть, что нужно сделать)
  • xUnit крепеж. Настройка и TearDown (часть «что делать») - платформы xUnit вызывают программу установки в начале и TearDown в конце (часть «когда нужно делать»)
  • Шаблон метода проектирования шаблона. часть шаблона метода when-to-do - примитивная реализация подкласса what-to-do
  • Методы контейнера DLL в COM. DllMain, DllCanUnload и т. Д. (Часть «что делать») - COM / OS (часть «когда делать»)
Автор: rpattabi Размещён: 22.07.2010 05:34

15 плюса

151 Репутация автора

Кажется, что самая запутанная вещь в «IoC» - аббревиатура и название, за которым оно стоит, - это то, что это слишком гламурное имя - почти шумное имя.

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

Автор: email.privacy Размещён: 19.01.2011 03:50

17 плюса

18309 Репутация автора

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

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

Когда кто-то хочет пить, она наполняет чашку, пьет и бросает чашку на пол.

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

Пусть инвертирует контроль.

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

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

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

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

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

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

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

Пример:-

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

}

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

Автор: Jainendra Размещён: 26.09.2012 05:54

11 плюса

1032 Репутация автора

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

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

Это говорит -

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

Автор: agaase Размещён: 22.02.2013 02:13

98 плюса

3314 Репутация автора

Инверсия Контроля (или IoC) - это получение свободы (Вы женаты, вы потеряли свободу и вас контролируют. Вы развелись, вы только что внедрили Инверсию Контроля. Это то, что мы назвали «разъединенными». Хорошая компьютерная система). препятствует некоторым очень близким отношениям.) больше гибкости (кухня в вашем офисе подает только чистую водопроводную воду, это ваш единственный выбор, когда вы хотите пить. Ваш босс внедрил Inversion of Control, установив новую кофемашину. Теперь вы получаете гибкость выбора водопроводной воды или кофе.) и меньшая зависимость (У вашего партнера есть работа, у вас нет работы, вы финансово зависите от своего партнера, поэтому вы находитесь под контролем. Вы нашли работу, вы внедрили Inversion of Control. Хорошая компьютерная система поощряет независимость.)

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

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

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

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

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

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

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

Автор: Luo Jiong Hui Размещён: 04.03.2013 07:33

41 плюса

3314 Репутация автора

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

Без IoC : вы просите «яблоко», и вам всегда подают яблоко, когда вы спрашиваете больше.

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

Итак, очевидно, что IoC предпочтительнее, когда вам нравятся сорта.

Автор: Luo Jiong Hui Размещён: 25.09.2013 02:00

143 плюса

3314 Репутация автора

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

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

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

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

Автор: Luo Jiong Hui Размещён: 25.09.2013 02:24

11 плюса

111 Репутация автора

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

  • При обычной разработке программного обеспечения вы пишете метод main () и вызываете «библиотечные» методы. Вы контролируете :)
  • В IoC «framework» управляет main () и вызывает ваши методы. Framework контролирует :(

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

В итоге ты всегда побеждаешь :)

Автор: Khanh Размещён: 19.09.2014 06:25

21 плюса

6608 Репутация автора

Я напишу мое простое понимание этих двух терминов:

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):
это общая характеристика сред, IOC управляет объектами Java
- от создания экземпляров до уничтожения через BeanFactory.
Компоненты Java, которые создаются контейнером IoC, называются bean-компонентами, а контейнер IoC управляет областью действия bean-компонента, событиями жизненного цикла и любыми функциями 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,

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

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

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

Детальное объяснение

Автор: VdeX Размещён: 10.11.2014 08:43

8 плюса

3760 Репутация автора

Программирование говорения

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

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

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

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

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

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

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

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

Автор: magallanes Размещён: 19.04.2015 12:07

3 плюса

0 Репутация автора

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

Автор: user4768611 Размещён: 13.05.2015 08:52

3 плюса

8591 Репутация автора

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

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

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

Автор: Rush Frisby Размещён: 16.07.2015 04:06

10 плюса

141 Репутация автора

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

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

Для тех, кто заинтересован в более глубоком рассмотрении Inversion of Control, была опубликована статья с изложением более полной картины Inversion of Control как шаблона проектирования (OfficeFloor: использование шаблонов office для улучшения проектирования программного обеспечения http://doi.acm.org/10.1145/ 2739011.2739013 с бесплатной копией, доступной для загрузки по адресу http://www.officefloor.net/about.html ).

То, что идентифицировано, является следующим отношением:

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

Резюме вышеуказанных отношений для Инверсии Контроля доступно - http://dzone.com/articles/inversion-of-coupling-control

Автор: Daniel Sagenschneider Размещён: 29.10.2015 04:27

21 плюса

1027 Репутация автора

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

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

Автор: user2330678 Размещён: 11.01.2016 12:49

3 плюса

189 Репутация автора

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

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

  1. Что это?

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

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

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

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

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

Автор: kusnaditjung tjung Размещён: 03.06.2016 01:46

9 плюса

5973 Репутация автора

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

Все начинается просто и показывает примеры кода.

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

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

Разве не достаточно того, что X знает, что использует то, что имеет поведение, методы, свойства и т. Д. Y, не зная, кто на самом деле реализует это поведение?

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

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

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

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

  • Х больше не зависит от Y
  • Более гибкая реализация может быть решена во время выполнения
  • Выделение блока кода, упрощение тестирования

...

Автор: DDan Размещён: 16.02.2017 02:03

6 плюса

167 Репутация автора

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

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

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

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

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

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

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

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

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

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

Ссылка:

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

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

Автор: Abdullah Al Farooq Размещён: 01.10.2017 11:24

10 плюса

710 Репутация автора

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

Классический код (без внедрения зависимостей)

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

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

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

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

  • Приложению нужен Foo, которому нужен Bar, которому нужен Bim, так:
  • Приложение создает Bim
  • Приложение создает бар и дает ему Бим
  • Приложение создает Foo и дает ему Бар
  • Приложение вызывает Foo
    • Фу называет бар
      • Бар что-то делает

Управление зависимостями инвертируется от одного вызываемого к одному вызывающему.

Какие проблемы это решает?

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

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

Вместо этого, если у вас был класс контроллера для создания объекта хранилища с 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, когда думаете, что есть (или могут быть) альтернативные реализации класса.

Автор: Raghavendra N Размещён: 04.11.2017 01:27

12 плюса

763 Репутация автора

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

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

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

Автор: mario1ua Размещён: 15.12.2017 06:35

4 плюса

158 Репутация автора

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

Автор: Sergiu Starciuc Размещён: 24.12.2017 06:34
Вопросы из категории :
32x32