Как анализировать зависимости в IDEA с помощью Dependency Structure Matrix и других инструментов.



Этот перевод продолжает серию об IntelliJ IDEA:



Матрица зависимостей


Эта функциональность доступна только в IntelliJ IDEA Ultimate, но не в Community версии.

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


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


Матрица структуры зависимостей (Dependency Structure Matrix или сокращенно DSM) может помочь вам визуализировать ваши зависимости и найти потенциальные проблемы. Во-первых, обязательно выполните команду build в свем проекте. Затем, чтобы запустить анализ, перейдя в меню «Analyze > Analyze Dependency Matrix...». Вам необходима редакция IDEA Ultimate и включить входящий в нее плагин DSM Analysis.


После завершения анализа вы увидите нечто похожее на это:



Чтобы лучше понять матрицу, посмотрите на следующий скриншот.



IDEA пропускает метки столбцов, чтобы сэкономить драгоценное пространство, но ведет себя так, как если бы они были там.


Каждая строка и столбец представляют пакет. Каждая ячейка представляет собой пересечение строки и столбца — это два пакета. Число в ячейке представляет количество зависимостей одного пакета от другого. Это означает, что один класс из исходного пакета использует другой класс из целевого пакета. Чем темнее клетка, тем больше зависимостей. Если существует более 99 зависимостей, он показывает ... вместо номера.


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


Визуальная помощь


Матрица является мощным инструментом, который может отображать много информации одновременно. Однако поначалу может быть трудно ее читать, если вы не привыкли работать с ней. Особенно со скрытыми колонками. К счастью, есть визуальная помощь, которая может помочь вам лучше понять зависимости.


Если вы наведите курсор мыши на ячейку, она покажет всплывающую подсказку, указывающую направление зависимости.



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



Строка выделяетмя цветом, а также соответствующий столбец, представляющий тот же пакет. Кроме того, вы можете видеть, что некоторые другие пакеты выделены либо желтым на зеленым цветом.


  • Желтым цветом выделены пакеты, от которых зависит выбранный пакет
  • Зеленым цветом маркируются пакеты, которые зависят от выбранного пакета

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



Нам нужно идти глубже


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


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



Циклические зависимости


Пока что мы рассмотрели только однонаправленные зависимости. Но то, к чему вы должны относиться очень осторожно, это циклические зависимости. В представлении DSM они отмечены красным:



Вы можете видеть, что класс Owner имеет 15 зависимостей от класса Pet, в то время как Pet имеет 5 зависимостей от Owner.


Выполнение действий


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


Вы даже можете реорганизовать свои классы прямо из представления DSM. Если щелкнуть ячейку с зависимостями, вы можете вызвать меню Find usages for dependencies. IDEA будет искать все места в одном из ваших классов / пакетов, где используется другой класс / пакет.


Давайте посмотрим на пример, чтобы быть более конкретным. Мы можем найти все места в пакете service, где используется что-либо из пакета vet. Результаты классифицированы по типу:



Теперь вы можете проверять вхождения по одному и проверить, можете ли вы улучшить ваши зависимости.


Анализ Maven зависимостей


Эта функциональность доступна только в IntelliJ IDEA Ultimate, но не в Community версии.

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


mvn dependency:tree -Dverbose -DoutputFile=dependencies.txt

Maven выведет ваше дерево зависимостей в текстовом формате, который может выглядеть примерно так (вот полный пример):


com.vojtechruzicka:spring-boot-actuator-example:jar:1.0.0-SNAPSHOT
+- org.springframework.boot:spring-boot-starter-actuator:jar:2.0.3.RELEASE:compile
|  +- org.springframework.boot:spring-boot-starter:jar:2.0.3.RELEASE:compile
|  |  +- org.springframework.boot:spring-boot:jar:2.0.3.RELEASE:compile
|  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:2.0.3.RELEASE:compile
|  |  +- org.springframework.boot:spring-boot-starter-logging:jar:2.0.3.RELEASE:compile
|  |  |  +- ch.qos.logback:logback-classic:jar:1.2.3:compile
|  |  |  |  \- ch.qos.logback:logback-core:jar:1.2.3:compile
|  |  |  +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.10.0:compile
|  |  |  |  \- org.apache.logging.log4j:log4j-api:jar:2.10.0:compile
|  |  |  \- org.slf4j:jul-to-slf4j:jar:1.7.25:compile
|  |  +- javax.annotation:javax.annotation-api:jar:1.3.2:compile
|  |  \- org.yaml:snakeyaml:jar:1.19:runtime

В дополнение к простому тексту, предлагаются различные другие форматы в качестве вывода, которые лучше подходят для представления графа зависимостей, такие как graphml или tgf.


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


ОБНОВЛЕНИЕ: Будьте осторожны с параметром verbose при использовании maven 3.x, так как под капотом он все еще использует алгоритм Maven 2 и может дать вам противоречивые результаты.

К счастью, IDEA предлагает инструмент с хорошим графическим интерфейсом для работы с графами зависимостей Maven. Этот инструмент уже давно используется в IntelliJ, но с версии 2019.1 он получил некоторые необходимые улучшения, которые делают его гораздо более полезным в проектах с большими графами зависимостей.


Чтобы показать график, зайдите в файл pom.xml и нажмите Shift + Ctrl + Alt + U (или ? + ? + ? + U на Mac). Или щелкните правой кнопкой мыши > Diagrams > Show Dependencies.


Вы увидите уменьшенный график зависимостей, где невозможно увидеть отдельные имена элементов, если вы не увеличите масштаб. Поиск отдельных элементов вручную может быть очень болезненным. К счастью, вы можете использовать команду Find как обычно, используя Ctrl + F.



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


Первый вариант — показать только прямых соседей. То есть только прямые зависимости текущего элемента и только элементы, которые напрямую зависят от выбранного элемента.



Обратите внимание, что это работает не только для отдельных элементов, но вы можете выбрать несколько элементов, удерживая кнопку Shift.


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



IDEA выделяет для вас конфликтующие зависимости красным цветом. Тем не менее, может быть трудно найти, если что-то не так в огромном дереве зависимостей. К счастью, вы можете фильтровать только проблемные части:



В приведенном выше примере вы можете увидеть конфликт между версиями JUnit. Существует явная зависимость от JUnit 3.8.1 и другой версии, транзитивно полученной через spring-boot-starter-test.


Плагин Maven Helper


Если графическое дерево зависимостей не то, что вам нужно, есть альтернатива для вас. Это плагин Maven Helper от Vojtech Krasa. Он использует иерархическое текстовое представление зависимостей, аналогично mvn dependency:tree, но с хорошими возможностями просмотра зависимостей.


Это также хорошая альтернатива, если вы используете IDEA Community Edition или используете более старую версию IDEA, где график зависимости Maven безполезен.


Чтобы использовать анализатор зависимостей, предлагаемый этим плагином, просто откройте любой файл pom.xml. Внизу вашего редактора появится новая вкладка под названием Dependency Analyzer, добавленная редактором.



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


Анализ Gradle зависимостей


Начиная с версии 2019.2, IDEA может наконец показать вам диаграмму зависимостей не только для Maven, но и для Gradle. Ура! Он работает почти так же, как диаграмма зависимостей Maven.


Просто зайдите в файл build.gradle и нажмите Shift + Ctrl + Alt + U (или ? + ? + ? + U на Mac). Или щелкните правой кнопкой мыши > Diagrams > Show Dependencies.


Заключение


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


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