Вы находитесь на странице: 1из 33

Dependency injection

Определение DI
Внедрение зависимостей представляет собой набор принципов и
приемов проектирования программных продуктов, позволяющий
разрабатывать слабосвязанный код.
Связанность, сопряжение (coupling)— способ и степень взаимозависимости между
программными модулями; сила взаимосвязей между модулями; мера того,
насколько взаимозависимы разные подпрограммы или модули

Low Coupling — это принцип, который позволяет распределить обязанности


между объектами таким образом, чтобы степень связанности между системами
оставалась низкой.
Устоявшиеся мифы о DI

DI актуально лишь для позднего связывания (late binding).


DI подходит лишь для модульного тестирования (unit testing).
DI — раздутая разновидность абстрактной фабрики (Abstract Factory).
DI не обходится без DI-контейнера.
Определение цели DI

Использование DI является не конечной целью, а средством достижения


определенного результата. Технология DI позволяет применять слабое связывание,
которое, в свою очередь, делает код сопровождаемым.
Пример сильной связанности
Пример слабой связанности
Null Object
Decorator
Linker
Adapter
Стабильные зависимости
Класс или модуль уже существует.
Ожидается, что новые версии не будут содержать критических.
Интересующие типы содержат детерминированные алгоритмы
Вы не рассматриваете необходимость замены, заключения в
оболочку, декориро-вания или перехвата класса или модуля другим
классом или модулем.
Нестабильные зависимости

Зависимость вводит требование по установке и конфигурированию среды


выполнения приложения.
Зависимость еще не существует или находится в стадии разработки.
Зависимость установлена не на всех машинах организации-разработчика.
Зависимость ведет себя недетерминированно.
Швы
Под швом (seam) понимается место, где приложе-
ние собирается из его составных частей — подобно тому как сшиваются друг с другом
части одежды. Шов также является местом, где можно разбить приложение на части
и изолированно поработать с модулями.
Швы
Простой пример: Hello DI!
Преимущества, получаемые от применения DI
Преимущество Описание Когда ценится

Ценится в стандартных
программных
Службы могут заменяться продуктах, но в меньшей
Позднее связывание другими службами без степени
перекомпиляции кода в корпоративных
приложениях
с четко заданной средой

Код может быть расширен


и повторно использован тем
Расширяемость способом, который ранее не Ценится всегда
был
явно запланирован
Преимущества, получаемые от применения DI
Преимущество Описание Когда ценится

Ценится в больших, сложных


Параллельная Код может разрабатываться приложениях, и меньше —
разработка в параллельном режиме в небольших, простых
приложениях

Классы с четко выраженной


Сопровождаемость ответственностью проще Ценится всегда
сопровождать
Преимущества, получаемые от применения DI
Преимущество Описание Когда ценится

Пригодность к Классы могут подвергаться


Ценится всегда
тестированию модульному тестированию
Внедрение через конструктор
Внедрение через конструктор (Constructor Injection) — это статическое опре-
деление списка требуемых зависимостей путем указания их конструктору
класса в качестве параметров

Граничный оператор (Guard Clause) проверяет, что


предоставленный объект
не является нулевым, и, если это так, выдает исключение.
Внедрение через конструктор
Когда следует использовать внедрение
через конструктор

Внедрение через конструктор должно стать вашим выбором по умолчанию для DI.
Оно относится к наиболее распространенному сценарию, где классу требуется одна
или несколько зависимостей, а приемлемые локальные реализации по умолчанию
(Local Defaults) недоступны.

Локальная реализация по умолчанию — реализация зависимости по


умолчанию, создаваемая в том же самом модуле или на том же уровне.
Преимущесва и недостатки внедрения через
конструктор

Преимущества Недостатки

Гарантированное внедрение. Среды, применяющие антипаттерн


Простота реализации. ограниченной
Статическое объявление конструкции, могут затруднить внедрение
зависимостей класса через конструктор
Преимущесва и недостатки внедрения через
конструктор

Преимущества Недостатки

Гарантированное внедрение. Среды, применяющие антипаттерн


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

Преимущества Недостатки

Позволяет вызывающему объекту


предоставлять Ограниченная применимость.
контекст конкретной операции. Заставляет зависимость
Позволяет внедрять зависимости в не превращаться
созданные в часть открытого API класса или его
внутри корня композиции объекты, абстракции
ориентированные на данные

Обычно внедрение через метод применяется в двух случаях:


когда потребитель внедренной зависимости меняется при каждом вызове
когда внедряемая зависимость меняется при каждом обращении к
потребителю
Внедрение через свойство

Внедрение зависимостей через свойство (Property Injection) позволяет заме-


нять локальную реализацию по умолчанию с помощью свойства, открытого
для установки его значения. Внедрение через свойство также известно как
внедрение через метод записи значения (Setter Injection).
Внедрение через свойство
Когда следует использовать внедрение
через свойство
Преимущества Недостатки

Не всегда просто добиться надежной реализации.


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

Корень композиции действует в качестве третьей стороны, которая соединяет


потребителей с их сервисами. Чем дольше откладывается решение о способе связи
классов, тем дольше сохраняется свобода выбора. Поэтому корень композиции
должен быть как можно ближе к точке входа приложения.

Перемещение компоновки классов за пределы корня композиции приводит


к созданию либо антипаттерна «Диктатор» (Control Freak), либо антипаттерна
«Локатор сервисов» (Service Locator).
Пример: реализация корня композиции
с использованием чистой технологии DI
Спасибо за внимание !

Вам также может понравиться