Я проектирую новую систему и хочу знать, что такое инверсия управления (IOC) и, что более важно, когда ее использовать.
Это должно быть реализовано с помощью интерфейсов или может быть сделано с помощью классов?
design
design-patterns
inversion-of-control
Джедай мастер жуткий
источник
источник
Ответы:
IoC (см. « Инверсия управления» в Википедии) применяется в тех случаях, когда компонент не может выполнить задачу полностью, поскольку у него нет необходимой информации или функций.
Простейшим примером шаблона IoC были бы функции обратного вызова в C. Например, вы можете объявить функцию:
Это повторяет
list
применениеf
функции к каждому элементу.Iterator
Функция не знает , как будет обрабатываться каждый элемент, вы просто указать функцию в качестве аргумента, и он обрабатывает их.Как показывает предыдущий пример, IoC позволяет вам разделить вашу программу на отдельные компоненты, которые не знают друг о друге. Одной из наиболее распространенных версий IoC является Dependecy Injection .
В Dependency Injection каждый компонент должен объявить список зависимостей, необходимых для выполнения его задачи. Во время выполнения специальный компонент (обычно), называемый контейнером IoC, выполняет связывание между этими компонентами. Он пытается предоставить значения для опубликованных зависимостей компонентов.
Вот пример в псевдокоде:
В этом примере класс
Foo
имеет конструктор, который требует аргумент типаBoo
для выполнения какого-либо действия.Вы можете создать экземпляр класса,
Foo
используя код, подобный следующему:MyContainer
- это контейнер IoC , который заботится о получении экземпляраBoo
и передаче егоFoo
конструктору.Таким образом, IoC позволяет разделить вашу программу на отдельные части. Это хорошо, потому что:
Однако в некоторых случаях IoC может усложнить понимание кода.
Если вы хотите увидеть хороший пример реального использования IoC , взгляните на Mircosoft Composite UI Application Block и CompositeWPF.
Я надеюсь, что мое объяснение поможет вам.
С уважением,
аку
источник
Поскольку я сам недавно в этом разбирался и сохранил все закладки, я нашел бесценным следующее для изучения IOC / DI.
Оригинальная статья Мартина Фаулерса о МОК / ДИ
Некоторые концепции, чтобы знать в первую очередь
Отличная коллекция учебников IOC / DI
Книга о IOC / DI из Manning Press
Исходный код и объяснение того, как создать свой собственный IOC - причина, по которой чтение исходного кода - это всегда лучший способ понять концепцию.
источник
Привет, JMS, в основном IoC / DI позволит вам определить, какую реализацию вы используете один раз, и сохранять статическую копию вашего контейнера для ссылки каждый раз, когда вы захотите ссылаться на нее.
Википедия, вероятно, поможет вам, но я хотел сослаться на вашу вторую часть - да, внедрение классов может быть сделано для классов (т. Е. Каждый раз, когда этот тип класса должен быть передан методу, используйте этот класс), но лучше используйте интерфейсы, потому что таким образом вы можете изменить, какую версию провайдера, репозитория и т. д. вы используете, просто сославшись на нее в своей настройке.
IE, скажем, у вас был интерфейс для чтения потока, и у вас были XMLStreamReader и реализация SQLStreamReader. Затем вы можете передать ссылку на интерфейс вашим методам, а затем в вашем контейнере IoC сообщить, какой из них использовать.
Таким образом, у вас может быть публичный List ReadPeople (читатель IStreamReader), и в настройках вашего контейнера IoC сообщайте ему всякий раз, когда вы ожидаете, что IStreamReader использует SQLStreamReader.
Затем, если вы передумаете позже, вам нужно будет изменить его только в одном месте (настройка вашего контейнера), и не будет иметь значения, сколько методов запрашивает IStreamReader, он всегда получит значение по умолчанию, которое вы указали своему контейнеру подавать.
источник
Допустим, у вас есть валидатор для проверки, является ли бизнес действительным в вашей системе. Ваш "BusinessValidator" может иметь поле типа AddressValidator, которое проверяет адресную часть бизнеса. Если вы хотите протестировать BusinessValidator без выполнения внешнего кода (то есть кода addressValidator), то, если вы использовали какой-то IoC / DI в своей инфраструктуре, вы можете легко «вставить» фиктивный addressValidator вместо него и не беспокоиться о тестировании. код выходит за рамки тестируемого класса.
источник