Инверсия управления
Инверсия управления (англ. Inversion of Control, IoC) — общий принцип программирования, особенно важный в рамках объектно-ориентированной парадигмы, используемый для уменьшения зацепления (связанности) в компьютерных программах[1]. Также архитектурное решение интеграции, упрощающее расширение возможностей системы, при котором поток управления программы контролируется фреймворком[2].
В обычной программе программист сам решает, в какой последовательности делать вызовы процедур. Но если используется фреймворк, программист может разместить свой код в определенных точках выполнения (используя callback или другие механизмы), затем запустить «главную функцию» фреймворка, которая обеспечит все выполнение и вызовет код программиста тогда, когда это будет необходимо. Как следствие, происходит утеря контроля над выполнением кода — это и называется инверсией управления (фреймворк управляет кодом программиста, а не программист управляет фреймворком).
Инверсия управления бывает не только во фреймворках, но и в некоторых библиотеках (но обычно библиотеки не создают инверсии управления — они предоставляют набор функций, которые должен вызывать программист).
Другим примером инверсии контроля можно считать облегчённые версии системных драйверов, так называемые фильтрующие драйверы. В этом случае основной поток управления реализуется ядром ОС и обычным «тяжёлым» драйвером, а конкретная функциональность реализуется за счёт функций обратного вызова (callback), которые фильтр регистрирует при старте. Собственно, такой же принцип работает и в случае других фильтров, будь то фильтрация видеопотока или потоков веб-запросов к java-сервлетам.
Описание
Одной из реализаций инверсии управления в применении к управлению зависимостями является внедрение зависимостей (англ. dependency injection)[2][3]. Внедрение зависимости используется во многих фреймворках, которые называются IoC-контейнерами.
Если сравнить с более низкоуровневыми технологиями, IoC-контейнер — это компоновщик, который собирает не объектные файлы, а объекты ООП (экземпляры класса) во время исполнения программы. Очевидно, для реализации подобной идеи было необходимо создать не только сам компоновщик, но и фабрику, производящую объекты. Аналогом такого компоновщика (естественно, более функциональным) является компилятор, одной из функций которого является создание объектных файлов. В идее компоновки программы во время исполнения нет ничего нового. Предоставление программисту инструментов внедрения зависимостей дало значительно бо́льшую гибкость в разработке и удобство в тестировании кода[4].
Примеры использования
- Шаблон «Фабрика» (англ. Factory pattern)
- Локатор служб
- Внедрение зависимости (англ. Dependency injection)
- Контекстный поиск (англ. contextualized lookup)
Критика
Все подходы, основанные на инверсии управления, страдают от следующих двух недостатков[5]:
- логика взаимодействия программы разбросана по отдельным обработчикам событий или классам;
- поток управления задан неявно и использует общее состояние (shared state) обработчиков событий.
Примечания
- ↑ Inversion of Control with the Managed Extensibility Framework (MEF) . Дата обращения: 6 октября 2016. Архивировано 4 января 2017 года.
- ↑ 1 2 Yang, 2012.
- ↑ Robert C. Martin. Clean Code: A Handbook of Agile Software Craftsmanship. — Pearson Education, 2008. — P. 157. — ISBN 978-0-13-608325-2.
- ↑ Martin Fowler. Inversion of Control Containers and the Dependency Injection pattern . Дата обращения: 6 октября 2016. Архивировано 30 мая 2020 года.
- ↑ 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.