Первый пост в публичном пространстве группы, попробую сделать его коротким (поскольку длинные писать не умею) и полезным. Речь пойдет о механизме dependency injection и переломе моего мозга. Сам шаблон ныне очень популярен особенно в энетерпрайзной среде, но я даже с довольно большим стажем программирования очень не с первого раза въехал в то, что это такое. После прочтения довольно обширной статьи в википедии на ум приходит только:
Я понял - это намёк,
Я всё ловлю на лету
Но непонятно
Что конкретно ты имела в виду
Группа "Несчастный случай"
В смысле, все вроде правильно, но где тут вся суть-то?
Идея такая: предположим у нас есть какой-то объект, которому для работы нужны другие объекты. Скажем, у нас есть транспортный код, естественно для проведения моделирования, нам нужны такие вещи, как геометрический трэккер, генератор случайных чисел и симулятор взаимодействий. Мы не разбираем случай, когда все это делается на уровне субрутин, и перемешано в одну большую кучу тыщ на 10 строк кода. Так давно уже никто не делает (ну ладно, про никто это я погорячился).
Внедрение или обращение зависимостей вообще имеет смысл только в объектном подходе, так что и говорим о нем, разумеется объектом может быть и функция. |
Теперь подумаем, а каким образом наш транспортный код будет генерировать эти вспомогательные объекты.
Собственно последний вариант и принято называть dependency injection. Вообще, разумеется вариант выглядит привлекательно. Дополнительный плюс в том, что так как сервис выдает объект по запросу, то генерация этого объекта, вообще говоря, может быть сделана в тот момент, когда он нужен, что может существенно оптимизировать время запуска программы. Каким образом эту довольно простую идею можно вытащить из того, что написано в википедии, я до сих пор не очень понимаю (особенно учитывая очень странное название).
А теперь к тому, с чего все это началось. Я сижу, изучаю тут код одних товарищей, которые очень любят этот самый dependency injection, и используют его вообще везде. При этом эксплуатируется очень ныне популярная библиотека Guice. Я сперва, читая их код, вообще ничего не понял, поскольку в коде вообще нет никаких запросов к сервису, управляющему зависимостей. Оказывается, guice занимается тем, что при создании объекта, проводит поиск всех полей этого объекта, помеченных специальной аннотацией (в Java и всяческих наследниках, аннотации кода - это своеобразная метапрограмма). После чего, система ищет в себе генератор для объектов того типа, который нужен клиенту и подставляет его. В процессе писания этого поста, я наконец понял, как оно работает и после этого, все кажется довольно изящным, но перед этим мозг был сломан.
Вообще, интерес к dependency injection у меня возник до этого. Дело в том, что при разработке контекстов для DataForge, я сам того не зная, эту концепцию переизобрел. Одна из функций контекста - это как раз "внедрение зависимостей", он тащит в себе набор некоторых сервисов, которые могут быть вызваны любыми клиентами, знающими об этом контексте. Конечно, там еще много всяческих прелестей вроде наследования и динамического переключения, но в смысле архитектуры они вторичны.