Dependency injection in Java
Кто расскажет нормально в чем заключается суть dependency injection в java (в чистой java без spring и других Фреймворков) Я понимаю что суть в том чтоб сделать кол более гибким и помочь использовать методы без создания экземпляра , но в итоге то экземпляр создается если говорить о реализации DI через конструктор , в конце мы все равно создаём экземпляр самого класса в котором метод потом экземпляр класса в котором используется метод из первого класса и потом в параметры второго экземпляра кидаем первый , и получается так чтоб данный класс имеет уже целых два экземпляра , и в чем суть тогда ? Прошу объясните подробнее пожалуйста.
Ответы (2 шт):
LocalDataSource localDS = new LocalDataSource();
RemoteDataSourceOne remoteDS = new RemoteDataSourceOne();
RemoteDataSourceTwo remoteDSTwo = new RemoteDataSourceTwo();
Repository repository = new RemoteDataSource(localDS, remoteDS, remoteDSTwo);
ViewModel vm = new ViewModel(repository);
допустим у тебя есть вот такая архитектура.
объект ViewModel надо создавать в разных местах, для разных задач.
и все работает хорошо, пока не наступит час "рефакторинга", в котором захочется класс LocalDataSource разбить на 2 более маленьких класса (разделить по функционалу).
следующие пару дней придется работать руками и выстраивать заново самому архитекруту, чтобы просто запустить проект (если не используется DI)
или взглянем с другой стороны. захотелось написать юнит-тесты и есть необходимость замокать класс RemoteDataSourceOne
без DI это так же станет лишними трудо-часами для разработчика.
DI хорошо показывает себя в команде разработчиков.
например, каждый из этих классов разрабатывает отдельный разработчик.
разрабочик класса ViewModel говорит "мне для работы моего класса нужны вот такие методы (и показывает желаемый интерфейс). мне без разницы как это будет работать под капотом, но мне надо чтобы это работало" и сидит пилит свой класс.
и так поступает каждый разработчик своих классов.
и тут сразу же можно увидеть пользу "почему DI работает на интерфейсах".
пока разработчик LocalDataSource пишет свой класс, он может подкинуть в DI какой-то мок, заглушку, своего класса, чтобы разработчик слоя повыше Repository, мог уже что-то делать (хоть и на заглушках).
а тот подкинет заглушку для разработчика ViewModel.
и когда каждый из них доделает свой класс, они просто поменяют свой модуль в DI и все будет работать само собой.
разработчикам верхних слоев не придется лезть в свой класс и ручками менять класс-заглушки на рабочий класс. все сделает за них DI.
как итог, DI нужен для:
- разделения ответственности
- возможности вкл/выкл заглушек
- написание юнит-тестов
DI не является чем-то незаменимым. без него так же спокойно можно разрабатывать и все будет точно так же.
но DI сильно облегчает разработку и помогает абстрагироваться от конкретных реализаций. помогает в пару кликов вместо существующей реализации включить заглушки или наоборот. помогает протестировать новый вариант уже существующего класса, без его прямой интеграции в проект.
Ну вот смотри, ты можешь все свои объекты создавать в отдельном классе учитывая все зависимости. И потом у этого класса можешь запрашивать нужные тебе в данный момент. Преимущества:
- Все выглядит проще
- Отделяешь код создания объектов от бизнес логики
- Упрощается управление и тестирование
- Можно использовать интерфейсы, делая код более адаптируемым к изменениям и более простым в обслуживании
- Можно, что выходит из 4 пункта, легко менять реализацию нужных объектов.