Является ли Inversion of Control специфичной для ОО-языков? - PullRequest
9 голосов
/ 04 мая 2009

Еще один способ задать этот вопрос: что такое Инверсия Контроля по вашему мнению?

Я задаю этот вопрос, потому что статья в Википедии о IoC была похищена по не-ОО-объяснению. Это взято со страницы обсуждения и от 2007 года:

Я позволил себе полностью переписать страницу, так как предыдущий контент был полностью поглощен бессмысленным "объектно-ориентированным" болтовней ...

Я не понимаю, как Inversion of Control имеет какой-либо смысл вне языка OO. Уже есть много объяснений отказа от управления в процедурных языках (программирование событий - одно), и чисто функциональные языки не нуждаются в таком понятии, как инверсия управления, поскольку они имеют функции более высокого порядка.

Кроме того, в статье , где Мартин Фаулер разрабатывает IoC, он исключительно обрабатывает ОО-примеры.

Итак, является ли IoC исключительно концепцией ОО и что это такое?

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

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

Для меня IoC является исключительно концепцией ОО.

Какой у вас ответ?

Ответы [ 4 ]

13 голосов
/ 04 мая 2009

Инверсия управления определенно не является концепцией ОО.

IoC существует и довольно часто используется в неOO-языках. Например, это очень часто встречается в Си. Ярким примером этого является Windows API - каждый раз, когда вы вызываете какие-либо функции Windows API, которые работают через обратные вызовы, вы в основном используете IoC в его наиболее примитивной форме.

Например, взгляните на функцию EnumWindows . Используя это, вы передаете указатель функции (EnumWindowsProc) в библиотеку, и ваш код запускается из кода библиотеки.

Сравните это с определением Inversion of Control из Википедии: «Инверсия управления происходит, когда библиотечная процедура вызывает пользовательские процедуры.»

Это точно так же.

Однако IoC действительно становится очень мощным, гибким и простым в использовании, когда вы добавляете систему с расширенным набором типов и многие другие инструменты, которые поставляются с ООП. Это делает его более распространенным, поскольку с ним «приятнее» работать, но он существовал до ООП.

11 голосов
/ 04 мая 2009

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

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

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

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

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

7 голосов
/ 04 мая 2009

Что ж, концепция «инверсии управления» кажется применимой везде, где у вас есть какой-то способ обойти указатели функций. По сути, концепции плагинов и библиотеки DLL с совместимыми сигнатурами (например, драйверы) являются не чем иным, как формой IoC.

Однако при использовании IoC с расширенным типом и моделью контейнера вы в основном автоматически попадете в мир OO. И концепции ООП очень хорошо соответствуют концепциям IoC, особенно в языках, которые поддерживают множественное наследование с чисто виртуальными классами (или «интерфейсами», как их еще называют).

1 голос
/ 04 мая 2009

На самом деле ОО реализация 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") } );

Ни один из этих примеров не является объектно-ориентированным, q.e.d ..

...