DIP vs IoC vs DI в мире Android

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.
Недавно меня спросили на собеседовании: “В чём разница между Dependency injection и Dependency inversion principle из SOLID”. Я знал определение каждого из них, но провести четкую границу между этими понятиями у меня не получилось. В этой статье я хочу кратко описать различие между понятиями Dependency inversion principle (DIP), Inversion of control (IoC) и Dependency injection (DI) на примере чистой архитектуры и Android фреймворка. Итак, поехали.

Dependency inversion principle


Определение
A. Модули верхних уровней не должны зависеть от модулей нижних уровней. Оба типа модулей должны зависеть от абстракций.
B. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.

В первом определении фигурирует понятие “модуль”. Это очень важное понятие без которого понять DIP не получится.

модуль — логически взаимосвязанная совокупность функциональных элементов

Чтобы не было недопонимания, рассмотрим определения на примере. Допустим, нам надо получить список прочитанных книг и вывести его пользователю. Для этого будем использовать классы BooksInteractor и BooksRepository. Каждый из этих классов положим в свой модуль BI и BR соответственно. Модуль класса BooksInteractor зависит от класса BooksRepository.



BooksInteractor’y нужно получить список книг из BooksRepository. Интерактору совершенно не важно, как репозиторий получит эти данные, а значит в данном случае BooksInteractor является абстракцией для BooksRepository. Согласно второму определению BooksInteractor (абстракиция) НЕ должен зависеть от BooksRepository (реализация). А вот репозиторий наоборот должен знать о модуле BI. Что ж это получается: интерактор должен лежать внутри репозитория? Нет, чтобы инвертировать зависимости, нам достаточно покрыть BooksRepository интерфейсом IBooksRepository, а этот интерфейс положить в модуль класса BooksInteractor. Теперь вернемся к 1-ому определению DIP и взглянем на диаграмму.



Смотрите-ка, модули верхних уровней (модуль BI) не зависят от модулей нижних уровней (модуль BR). А оба модуля зависят от абстракции (от интерфейса IBooksRepository). Если вы уловили магию инвертирования зависимости с помощью покрытия репозитория интерфейсом, вы поняли принцип инверсии зависимостей. Поздравляю! Самое сложное вы поняли. Подробнее почитать про DIP можете в этой статье на хабре.

Inversion of Control


Мы изучили понятие «принцип инверсии зависимостей». Теперь перейдем к ещё одной инверсии — инверсии контроля. Само понятие очень обширно и в программировании может означать одно из трех:
1) Инверсия интерфейсов — делегирование взаимоотношения между модулями посреднику-интерфейсу. Где это применяется? Например, в DIP, который мы изучили ранее.
2) Инверсия создания — делегирование создания и связывания зависимостей посреднику (фабрики, DI/IOC контейнеры)
3) Инверсия процесса — делегирование контроля над своей программой фреймворку, который сам управляет последовательностью вызовов функций. Первое, что приходит на ум в качестве примера, — Android фреймворк. Ты расширяешь класс Activity и Fragment, отдавая контроль над их жизненным циклом фреймворку.

Dependency Injection


Dependency injection (внедрение зависимостей) — это механизм передачи классу его зависимостей. С этим вы всегда встречаетесь, когда нужно передать зависимость в другой класс. Существует несколько способов внедрения зависимостей: через конструктор (Constructor Injection), через метод (Method Injection) и через свойство (Property Injection). Каждый из этих методов используется для своих целей. Но тут важно понять, что Dependency Injection — это всего лишь передача зависимости в конструктор, метод или свойство

Рассматриваем edge cases


  • Может ли быть DI без IoC и DIP? Да, может. Создаем экземпляр конкретного класса A и передаем его в объект класса B через конструктор, метод или свойство.
  • Может ли быть DIP без IoC? Нет, DIP является одним из способов реализации Инверсии интерфейсов в IoC.
  • Может ли быть DIP без DI? Да, мы можем завязать нижние модули на интерфейс. Классы верхнего модуля будут работать с интерфейсом-абстракцией, но конкретная реализация класса нижнего модуля будет создаваться в конструкторе верхнего модуля.


Узнать отличия DIP, DI и IoC от других авторов можно тут и тут.

Буду рад вашим комментариям и отзывам!
Источник: https://habr.com/ru/post/528606/


Интересные статьи

Интересные статьи

Я стал счастливым обладателем новых часов. Тех самых, которые, наверное, было бы правильнее называть компьютером с ремешком, чем часами, но всё же. В спальне, над кроватью была LED ле...
В интернет-магазинах, в том числе сделанных на готовых решениях 1C-Битрикс, часто неправильно реализован функционал быстрого заказа «Купить в 1 клик».
Унаследованная инфраструктура до сих пор является важной частью предприятий во многих отраслях промышленности: в медицинских организациях, которые всё ещё используют систему «Windows XP», в б...
Еще не так давно музыкальная индустрия была «закрытым клубом». Попасть в него было тяжело, а общественный вкус находился под контролем небольшой группы «просветленных» экспертов. Но с каждым г...
Привет, Хабр! В данной статье, ориентированной на новичков, я бы хотел дать несколько советов по оптимизации использования приложением памяти устройства, дабы постоянно не получать OutOfMemory, а...