• Зачем нужен Dependency Injection в Android разработке?

    @sapl
    У меня не ответ, а уточнение вопроса.
    Зачем DI на сервере (Spring) понятно.
    Но в Android всегда один пользователь, одна сессия и всегда есть singleton Application, где многое инициализируется и который везде доступен через Context. И как не крути Context везде есть и ничего в этом нет страшного.
    Чем плох вариант использования одного модуля (Application), который отдается все нужные зависимости?
    Мало того даже при использовании dagger все равно везде дергается тот самый Application чтобы получить компонент для вызова inject.
    PS. Также немного путают примеры по Dagger где инжектится этот самый context, зачем его инжектить, если он итак везде есть?
    Ответ написан
    5 комментариев
  • Зачем нужен Dependency Injection в Android разработке?

    artemgapchenko
    @artemgapchenko
    Начать неплохо бы с понимания того, что такое DI. Обратимся к википедии:

    Внедрение зависимости (англ. Dependency injection, DI) — процесс предоставления внешней зависимости программному компоненту.

    Если выражаться не канцеляритом, а обычным русским языком, то DI - это когда вы своему компоненту (например, классу) предоставляете нужные для него зависимости извне, а не создаете их сами в конструкторе, или через инициализацию в месте объявления поля. То есть не так:

    public class Api {
    	....
    	private final HttpClient client = new OkClient();
    }

    А, например, так:

    public class Api {
    	....
    	private final HttpClient client;
    
    	public Api(@NonNull HttpClient client) {
    		this.client = client;
    	}
    }


    И что нам это даёт?

    Ну, очевидно, нам теперь проще менять зависимости. Нужна вам другая реализация абстрактного класса HttpClient - взяли, и передали её через конструктор, или через метод-setter. В случае с первым куском кода, вам пришлось бы ещё и класс Api переписывать, что в случаях, отличных от тривиальных, может привести к ошибкам. Получается, что ваш класс теперь закрыт от изменений (смотрим Open/Closed Principle).

    Окей, а на практике-то какие бенефиты?

    Во-первых, вы теперь можете написать инициализацию вашей программы через конфигурационные файлы. Скажем, на старте будет читаться простенький текстовый файл, который определяет, какой httpclient использовать, какие настройки доступа к бд применять и так далее, и, исходя из этого, будут определяться зависимости.
    Во-вторых, вам теперь существенно проще писать тесты. Написали вы, скажем, какой-нибудь парсер, который принимает InputStream, содержащий в себе данные json-объекта, как-то хитро его парсит, и выдаёт вам объект вашей бизнес-модели. В приложении этот парсер будет принимать на вход реализацию InputStream'а, которая берёт данные из сети, а в тестах - реализацию, которая просто читает файл с диска (потому что тесты должны выполняться часто и быстро, и ваша задача в тесте - протестировать ваш парсер, а не скорость сетевого соединения).

    Вот, в общем-то, и всё. А Dagger - это просто библиотека, которая автоматизирует ручное внедрение зависимостей, равно как и другие DI-библиотеки.

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