Инверсия управления

Перейти к навигацииПерейти к поиску

Инверсия управления (англ. Inversion of Control, IoC) — общий принцип программирования, особенно важный в рамках объектно-ориентированной парадигмы, используемый для уменьшения зацепления (связанности) в компьютерных программах[1]. Также архитектурное решение интеграции, упрощающее расширение возможностей системы, при котором поток управления программы контролируется фреймворком[2].

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

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

Другим примером инверсии контроля можно считать облегчённые версии системных драйверов, так называемые фильтрующие драйверы. В этом случае основной поток управления реализуется ядром ОС и обычным «тяжёлым» драйвером, а конкретная функциональность реализуется за счёт функций обратного вызова (callback), которые фильтр регистрирует при старте. Собственно, такой же принцип работает и в случае других фильтров, будь то фильтрация видеопотока или потоков веб-запросов к java-сервлетам.

Описание

Одной из реализаций инверсии управления в применении к управлению зависимостями является внедрение зависимостей (англ. dependency injection)[2][3]. Внедрение зависимости используется во многих фреймворках, которые называются IoC-контейнерами.

Если сравнить с более низкоуровневыми технологиями, IoC-контейнер — это компоновщик, который собирает не объектные файлы, а объекты ООП (экземпляры класса) во время исполнения программы. Очевидно, для реализации подобной идеи было необходимо создать не только сам компоновщик, но и фабрику, производящую объекты. Аналогом такого компоновщика (естественно, более функциональным) является компилятор, одной из функций которого является создание объектных файлов. В идее компоновки программы во время исполнения нет ничего нового. Предоставление программисту инструментов внедрения зависимостей дало значительно бо́льшую гибкость в разработке и удобство в тестировании кода[4].

Примеры использования

Критика

Все подходы, основанные на инверсии управления, страдают от следующих двух недостатков[5]:

  • логика взаимодействия программы разбросана по отдельным обработчикам событий или классам;
  • поток управления задан неявно и использует общее состояние (shared state) обработчиков событий.

Примечания

  1. Inversion of Control with the Managed Extensibility Framework (MEF). Дата обращения: 6 октября 2016. Архивировано 4 января 2017 года.
  2. 1 2 Yang, 2012.
  3. Robert C. Martin. Clean Code: A Handbook of Agile Software Craftsmanship. — Pearson Education, 2008. — P. 157. — ISBN 978-0-13-608325-2.
  4. Martin Fowler. Inversion of Control Containers and the Dependency Injection pattern. Дата обращения: 6 октября 2016. Архивировано 30 мая 2020 года.
  5. Agha, G. and Igarashi, A. and Kobayashi, N. and Masuhara, H. and Matsuoka, S. and Shibayama, E. and Taura, K. Concurrent Objects and Beyond: Papers dedicated to Akinori Yonezawa on the Occasion of His 65th Birthday. — Springer Berlin Heidelberg, 2014. — P. 433. — ISBN 9783662444719.

Литература

  • Yang, H. Software Reuse in the Emerging Cloud Computing Era. — Information Science Reference, 2012. — P. 54. — ISBN 9781466608986.

Ссылки

  • Martin Fowler. InversionOfControl (англ.). Дата обращения: 5 ноября 2013.
  • Вольный перевод статьи Мартина Фаулера "Inversion of Control Containers and the Dependency Injection pattern". InversionOfControl. Дата обращения: 10 декабря 2014.