инверсия управления (IoC) — это принцип проектирования, в котором специально написанные части компьютерной программы получают поток управление из общей структуры.
Фреймворком может быть Java Spring Framework, но мы также можем реализовать инверсию управления, используя:
Так почему же определение инверсии управления в Википедии ограничено рамками?
Внедрение зависимостей — это буквально еще одно название инверсии управления.
В обычной программе программист сам решает, в какой последовательности производить вызовы процедур. Но если используется фреймворк, программист может разместить свой код в определенных точках выполнения (с помощью обратного вызова или других механизмов), а затем запустить «основную функцию фреймворка», которая будет обрабатывать все выполнение и вызывать код программиста, когда это необходимо. В результате происходит потеря контроля над выполнением кода — это называется инверсией управления (фреймворк управляет кодом программиста, а не программист, контролирующий фреймворк).
Я думаю, что вы интерпретируете слово «фреймворк» гораздо более конкретно, чем это означает статья в Википедии. По большей части WP, похоже, имеет в виду это в самом общем смысле. Чтобы IoC работал, должно быть что-то, вызывающее методы объектов, предоставляемых приложением. Это «что-то» — основа.
@Дэвид Конрад нет, внедрение зависимостей — это не то же самое, что инверсия управления
@JohnBollinger, возможно, вы правы в том, что здесь «структура» — это нечто более широкое.
@AleksanderChelpski Во всех контекстах, которые я когда-либо слышал, они используются как взаимозаменяемые.
@David Насколько я понимаю, которое может быть ошибочным/неполным, DI — это просто возможность передавать зависимости объекту, будь то через параметр конструктора, параметр метода или напрямую устанавливая поле. Это можно сделать «вручную» или «автоматически». Ручной DI не использует структуру IoC (это просто «обычный» код). Но для автоматического внедрения зависимостей требуется какая-то структура IoC, которая может создавать и передавать объекты за вас (на основе некоторой конфигурации). В этом контексте я не удивлен, что DI и IoC используются как взаимозаменяемые, поскольку большую часть времени обсуждается «автоматический DI».
Википедия часто ошибается в технических вопросах, поскольку ее обычно редактируют авторы, не относящиеся к технической сфере. Этот ответ может пролить некоторый свет: stackoverflow.com/a/65588618/1371329.
«Правильно ли определение «инверсии управления» в Википедии?»
Да, это.
Прежде всего, ваш список содержит шаблоны проектирования. Шаблон проектирования не может быть основой (поскольку вы аннотировали свой список замечаниями о том, что, например, шаблон Factory не является основой, позволяющей доказать, что статья в Википедии неверна). Конечно, шаблоны проектирования не являются фреймворками. И шаблоны проектирования не являются «реализацией» IoC. Платформы используют эти шаблоны проектирования для реализации IoC.
Определение фреймворка ясно. Поскольку вы используете Википедию в качестве источника, вы также можете использовать Википедию для поиска того, как она описывает структуру:
«В компьютерном программировании программная среда — это абстракция, в которой программное обеспечение, обеспечивающее общие функции, может выборочно изменяться дополнительным написанным пользователем кодом, обеспечивая тем самым программное обеспечение, специфичное для приложения». Википедия
Теперь, используя это определение, мы можем ответить на ваш вопрос:
«Так почему же определение инверсии управления в Википедии ограничено рамками?»
Мы должны различать IoC и инверсию зависимостей.
Написание кода, зависящего от абстракций, следует принципу инверсии зависимостей. Это не IoC.
Создание экземпляра и внедрение реализации абстрактного типа и управление временем жизни этого экземпляра — это внедрение зависимостей, но все же не IoC.
Однако, если компонент, реализующий инверсию зависимостей (для отделения клиентского кода от внутреннего кода), квалифицируется как платформа, поскольку он инкапсулирует общие функции и поведение, которые можно расширять с помощью внешнего кода, который заранее определен как абстракции (инверсия зависимостей) и вызывается. в соответствии с этой структурой мы называем это IoC. Это просто определение.
IoC — это особый случай инверсии зависимостей, поскольку он фокусируется на зависимости между библиотекой и ее клиентами.
Другими словами, чтобы сделать библиотеку расширяемой с помощью клиентского кода (т. е. модифицировать или специализировать выборочную универсальную предопределенную функциональность), нам необходимо инвертировать управление потоком между компонентами (клиентом и библиотекой). Помните, что библиотека всегда вызывается клиентским кодом: поток управления передается от клиента к библиотеке. Идея инвертирования этого потока управления называется IoC.
Библиотека, у которой инвертирован поток управления, называется фреймворком. Это означает, что IoC не ограничивается фреймворками, фреймворки являются результатом прикладного IoC.
Фреймворк — это особая форма библиотеки (набор повторно используемых функций, поведений и других видов ресурсов).
Основная характеристика заключается в том, что структура реализует шаблоны проектирования для реализации принципа инверсии управления (IoC). Поток управления меняется на обратный: специализированный и расширяющий код (клиентский код, код высокого уровня) больше не вызывает код библиотеки (код низкого уровня). Вместо этого платформа вызывает клиентский код (код низкого уровня вызывает код высокого уровня). Это должно подчеркнуть, что основное внимание уделяется управлению функциональностью, а не зависимостям.
Основное внимание в IoC уделяется расширению инкапсулированной универсальной функциональности/поведения, где код платформы низкого уровня вызывает код клиента высокого уровня. Целью IoC не является разделение, хотя фреймворкам необходимо отделять свои внутренние компоненты от внешних.
Целью является эффективная расширяемость и специализация существующих общих функций/поведения.
Все упомянутые вами шаблоны проектирования эффективно помогают инвертировать управление потоком или отношениями вызывающего абонента. Однако реализация таких шаблонов проектирования, как внедрение зависимостей, сама по себе не делает библиотеку квалифицируемой как фреймворк.
У вас есть (а) общая функциональность, которую можно (б) расширить и специализировать путем подключения пользовательского/внешнего кода и которая (в) не требует и не допускает внесения изменений для расширения/вызова клиентского кода. Согласно этому определению, фреймворк может представлять собой один класс или тысячи классов. Это зависит от функциональности, которую он предоставляет.
Простой класс, выполняющий операцию над двумя операндами (например, калькулятор), также может квалифицироваться как платформа, в которой вы расширяете функциональность, предоставляя фактические операции, которые затем выполняет платформа (калькулятор) (IoC). Этот калькулятор будет создавать деревья выражений, а также реализовывать и обеспечивать арифметические правила, обеспечивать историю или поведение отмены/повтора и т. д. — общие функции калькулятора.
Теперь у вас есть небольшая структура калькулятора: «[...] общая функциональность, [которая] может быть выборочно изменена дополнительным написанным пользователем кодом.» из-за инверсии потока управления (IoC).
В фреймворках нет ничего волшебного. Это всего лишь реализации IoC. IoC обычно достигается путем реализации определенных шаблонов проектирования. Другими словами, если вы можете реализовать IoC, у вас всегда есть набор функций, которые можно назвать библиотекой. Библиотека, применяющая IoC, представляет собой фреймворк:
У фреймворков есть ключевые отличительные особенности, которые отличают их от обычных библиотек:
- Инверсия управления. В фреймворке, в отличие от библиотек или стандартных пользовательских приложений, общий поток управления программой определяется не вызывающей стороной, а фреймворком. Обычно это достигается с помощью шаблона метода шаблона.
- поведение по умолчанию [определяет библиотеку]: оно может быть предоставлено с помощью инвариантных методов шаблона метода шаблона в абстрактном классе, предоставляемом платформой.
- расширяемость: пользователь может расширить структуру (обычно путем выборочного переопределения) или программисты могут добавить специализированный пользовательский код для обеспечения определенных функций. Обычно это достигается с помощью метода-перехватчика в подклассе, который переопределяет метод шаблона в суперклассе.
- неизменяемый код платформы: код платформы, как правило, не подлежит изменению, хотя он принимает расширения, реализуемые пользователем. Другими словами, пользователи могут расширять структуру, но не могут изменять ее код.
Википедия
Итак, фреймворк может быть классом, IoC-контейнером или библиотекой, да?
Теоретически класс может быть фреймворком, если он следует принципу IoC. Определение фреймворка не определяет, из скольких классов он должен состоять. Все дело в расширяемой универсальной функциональности. Следуя другим принципам объектно-ориентированного проектирования, вы, скорее всего, получите более одного класса. IoC-контейнер может быть основой, если он удовлетворяет условиям. Применение IoC само по себе не создает основу (см. список).
Контейнер IoC обычно соответствует принципу IoC и сам по себе может считаться платформой или частью платформы. В конце концов, IoC-контейнер — это набор классов, отвечающих за управление зарегистрированными зависимостями. Итак, ответ на ваш первый вопрос (о классах) отвечает на второй вопрос о контейнерах IoC.
Библиотека — это библиотека, а не фреймворк. Это библиотека, предварительная стадия фреймворка. Если библиотека следует принципу IoC (т.е. инвертирует поток управления), то она становится фреймворком. Я разместил критерии, которым необходимо удовлетворять, чтобы назвать компонент фреймворком (последние четыре пункта списка).
IoC — это один из способов удалить зависимости от конкретных типов. Посмотрите принципы SOLID: Learn.microsoft.com/en-us/archive/msdn-magazine/2014/may/…