58.08
Rating
Retail Rocket
Retention Management Platform
19 August

Почему автоматическая регистрация зависимостей — зло

Retail Rocket corporate blogProgrammingPerfect codeDesigning and refactoringООP
image

Есть много проектов типа Simple Injector для различных языков программирования, позволяющих по имени класса, интерфейса или неймспейса, а иногда и папки зарегистрировать класс или всю группу классов, объединенных этим признаком, в каком-то регистре. Это делается для цели автоматического инстанцирования объекта без явного указания его зависимостей. Такую регистрацию группы объектов по общему признаку в регистре с целью дальнейшего инстанцирования я называю автоматической регистрацией зависимостей.

Если вы явно инстанцируете класс при его регистрации в регистре зависимостей, то это я не отношу к теме этой статьи.

А что в этом плохого?


В этом посте я расскажу о моем недовольстве, возникшем при работе с проектами, в которых применяется автоматическая регистрация зависимостей. Давайте по порядку.

Runtime vs compile time


Используя инструмент автоматической регистрации зависимостей, мы переносим проверку полноты зарегистрированных зависимостей в runtime. То есть, если на момент запуска программы у нас не окажется имплементации интерфейса, нужного для выполнения кода, мы узнаем об это в лучшем случае на старте приложения, а в худшем — уже при эксплуатации системы и от пользователей.

Вот пример. Если в проекте регистрация каких-то классов произошла, скажем, по их неймспейсу, а вы в какой-то момент переместили класс из него, то о проблеме вы узнаете в runtime. То же самое произойдет и при автоматической регистрации по интерфейсу, с той лишь разницей, что перемещение проблемой не будет, но вот снятие интерфейса приведет к проблеме, о которой вы узнаете после запуска приложения.

Рефакторинг кратно усложняется


Не только рефакторинг, но и изучение кода становится занятием весьма затруднительным. Всё потому, что при использовании автоматической регистрации зависимостей теряется доступ к современным возможностям сред разработки, которые позволили бы нам в один клик (find reference) узнать, кто использует этот класс, и ответить на следующие вопросы:

  • Могу ли я удалить этот класс?
  • Могу ли я перенести этот класс в другой namespace/папку?

и прочее.

В сумме с тем, что мы лишены возможности проверить полноту необходимых зависимостей при компиляции, любой рефакторинг — это упование на то, что у нас есть runtime-механизм в виде тестов, верификаций деревьев зависимости и подобного. И надежда, что он сработает. Следует отметить, что эти механизмы не только не гарантируют на 100%, что композиция кода корректна, но и значительно медленнее, чем компиляция.

Сокрытие реальной сложности системы


При ручном инстанцировании классов и всех их зависимостей вас может неслабо напугать монструозность файла, в котором всё это действо будет происходить. Смотря на тысячи строк кода инстанцирования классов и сравнивая их с десятком при использовании автоматической регистрации зависимостей, очень хочется поддаться искушению и перейти на «темную сторону».

Но о чем нам говорят эти тысячи строк кода инстанцирования объектов? О том, что этот модуль сложный, большой и нам следует подумать или о его структурировании через выделение подмодулей (которые сами явно инстанцирует свои зависимости), или над разделением этого модуля на несколько.

Это может показаться абстрактным, но убирание с глаз таких неудобных моментов как инстанцирование сотен объектов приводит к тому, что размер проекта неконтролируемо растет, и в итоге мы пропускаем момент, когда его следовало бы разделить на несколько проектов.

Лишние зависимости


Регистрируя зависимости и не контролируя их использование, мы рано или поздно приходим к ситуации, когда при старте приложения регистрируется значительно больше классов, чем реально требуется. Простое добавление в папку или имплементация интерфейса может привести к тому, что этот класс будет зарегистрирован в общем регистре.

Summary


Можно ли жить со всеми этими минусами и не замечать их? Конечно! Но я считаю, что это вырабатывает неправильные привычки разработки. Дело в том, что компиляция и типизация кода — это инструменты проверки корректности системы. Отказываясь от них, мы приходим к тому, что система становится хрупкой, поэтому разработчики боятся что-либо в ней менять. А страх разработчиков менять код уже приводит к тому, что качество кодовой базы деградирует, после чего внесение изменений в такой код становится процессом дорогостоящим.

Что хорошего в автоматической регистрации зависимостей?


А и правда, что хорошего? Предлагаю в комментариях подискутировать, почему же этот метод набрал популярность. Наверняка же у него есть поклонники среди читателей.
Tags:retailrocket dependency injection
Hubs: Retail Rocket corporate blog Programming Perfect code Designing and refactoring ООP
+14
4.8k 25
Comments 91
Information
Founded

26 March 2013

Location

Россия

Employees

101–200 employees

Registered

26 September 2014