Всем привет, читатели Habr! В этой статье я расскажу про DI (Dependency Injection) и также покажу, как я использую его на практике. Погнали!
Сначала простыми словами про DI
Недавно я скачал приложение, которое показывает сколько времени я провожу в своем смартфоне и мою зависимость от него. Что ж, в некоторые дни я проводил больше 5 часов и мне показало сильную зависимость. У меня Xiaomi Redmi Note 8.
На первый взгляд может показаться, что я завишу конкретно от моего Xiaomi. Однако это не так. Был бы у меня любой другой смартфон, результаты бы не изменились. В итоге получается, что я имею зависимость от абстракции - смартфон, а мой текущий - его конкретная реализация. Настало время переходить к практике!
Теперь к практике
Представим себе такую ситуацию, что каждую первую неделю вы должны показывать заказчику UI с моканными данными, а уже в конце спринта полностью готовую логику. Я надеюсь вы знакомы с паттерном Repository, который отвечает за получение данных, если нет - рекомендую ознакомиться. Самый простой способ решение проблемы - написать в репозитории методы, которые отдают моканные данные, а потом добавить методы для получения реальных данных (или заменить). Однако, поступая таким образом, мы нарушаем один из принципов SOLID, а именно Single Responsibility. Как быть в таком случае? Создать абстрактный класс нашего репозитория и после этого сделать 2 реализации, одна из которых отвечает за моканные данные, а другая - за реальные. И в Bloc или в любой другой класс, который отвечает за State Managment, вы инжектите абстракцию, тем самым давая возможность заменить репозиторий с моками на репозиторий для реальных данных.
Тем самым вы можете сначала заинжектить сначала репозиторий для моков, а потом заменить его на репозиторий, который получает данные с сервера.
Время повышать уровень
Однако мы должны постоянно повышать свой уровень! И давайте сейчас его повысим :)
Под буквой O в SOLID обозначается принцип открытости/закрытости. Он декларирует, что программные сущности должны быть открыты для расширения, но закрыты для изменения.
Когда мы заменяем одну реализацию на другую, то тем самым нарушаем этот принцип. И разработчики пакета Injectable тоже об этом подумали, поэтому мы можем создавать наши зависимости под разными environments. Для этого нам нужно будет под каждый environment создать main файл, описать их все в launch.json и проинить с каждого файла зависимости с определенным environment.
И после всех этих махинаций мы можем сделать так, тем самым соблюдая принцип открытости/закрытости.