Является ли инверсия управления специфичной для языков OO?
-
03-07-2019 - |
Вопрос
Другой способ задать этот вопрос -:что, по вашему мнению, такое Инверсия контроля?
Я задаю этот вопрос, потому что в статье Википедии о МоК был захвачен объяснением, не относящимся к OO.Это взято из страница обсуждения и ведется с 2007 года:
Я взял на себя смелость полностью переписать страницу, поскольку предыдущее содержимое было полностью поглощено бессмысленной "объектно-ориентированной" болтовней ...
Я не понимаю, как Инверсия управления имеет какой-либо смысл вне языка OO.Уже есть много объяснений отказа от управления в процедурных языках (событийное программирование - одно из них), а чисто функциональные языки не нуждаются в такой концепции, как инверсия управления, поскольку у них есть функции более высокого порядка.
Кроме того, в Статья там, где Мартин Фаулер подробно рассказывает о IoC, он работает исключительно с примерами OO.
Итак, является ли МоК исключительно концепцией OO, и что это такое на самом деле?
На мой взгляд, IoC пытается превратить функции в данные в рамках ограничений, налагаемых большинством языков OO, и пытается передать эти функции как данные в качестве аргументов другим функциям.Это не единственная часть работы МоК, но кое-что из этого есть.
Существует также шаблон проектирования factory, в котором деревья объектов создаются и настраиваются перед передачей дальше.
Для меня МоК - это исключительно концепция ОО.
Каков твой ответ?
Решение
Вы смотрите на теоретическую проблему с точки зрения реализации. Первый вопрос, который возникает, должен точно, какой контроль вы инвертируете ?
Тогда вы поймете, что не важно, какой объект, метод, функция или еще что-то передается, а то, что на самом деле делает код.
Короче говоря, когда вы делаете Dependency Injection, вы инвертируете контроль создания и использования зависимостей (ресурсов).
Когда вы указываете функции Windows API указатель на функцию обратного вызова, вы предоставляете им контроль над вызовом вашей функции со своими собственными параметрами.
Итак, вы видите, IoC - это просто теоретическая концепция, и, конечно, могут быть разные практические реализации.
Другие советы
Инверсия контроля, безусловно, не является концепцией ОО.
IoC существует и довольно часто используется в неOO-языках. Например, это очень часто встречается в Си. Ярким примером этого является Windows API - каждый раз, когда вы вызываете какие-либо функции Windows API, которые работают через обратные вызовы, вы в основном используете IoC в его наиболее примитивной форме.
Например, взгляните на функцию EnumWindows . Используя это, вы передаете указатель функции (EnumWindowsProc) в библиотеку, и ваш код запускается из кода библиотеки.
Сравните это с определением Inversion of Control из Википедии: " Инверсия управления происходит, когда библиотечная процедура вызывает пользовательские процедуры. "
Это точно так же.
Однако IoC действительно становится очень мощным, гибким и простым в использовании, когда вы добавляете систему с расширенным набором типов и многие другие инструменты, поставляемые с ООП. Это делает его более распространенным, так как это «лучше» работать, но он существовал до ООП.
Ну, концепция "инверсии управления" кажется применимым везде, где есть какой-то способ передачи указателей на функции. По сути, концепции плагинов и библиотеки DLL с совместимыми сигнатурами (например, драйверы) являются не чем иным, как формой IoC.
Однако при использовании IoC с расширенным типом и моделью контейнера вы в основном автоматически попадете в мир OO. И концепции ООП очень хорошо соответствуют концепциям IoC, особенно в языках, которые поддерживают множественное наследование с чисто виртуальными классами (или «интерфейсами», как их еще называют).
На самом деле, OO-реализация IoC довольно сложна, потому что функции не часто являются гражданами первого класса.
Как упоминал Аздер:IoC используется по многим причинам.Я кратко изложу некоторые из них здесь, чтобы убедить :)
Итерация
#ruby
{1,2,3}.each{ |i| puts i }
#haskell
map [1,2,3] ( \i -> write i )
//the stl algorithms
int printint( int i ){ return printf( "%d", i ); }
std::foreach( onetwothree.begin(), onetwothree.end(), &printi );
Создание потока
CreateThread( NULL, 0, &myFunction, NULL, 0, NULL );
Отправка общих событий
//javascript
document.getElementById( "mybutton" )
.addEventListener(
function(e){ alert("buttonPressed") } );
Ни один из этих примеров не является объектно-ориентированным, т.е..