Введение
Сегодня в любой более-менее серьезной компании, где настроен CI/CD, используется SonarQube. Это уже стандарт де-факто. Он умеет определять code smells, дублирование, уровень покрытия тестами, распознавать недостижимый код и многое другое. Настроили, подключили к CI — и вроде бы все хорошо.
Но…
Иногда SonarQube оказывается недостаточно злым. Он легко пропускает:
-
классы с кучей скрытых зависимостей
-
запутанную бизнес-логику, размазанную по методам
-
высокий coupling при почти идеальных метриках на дашборде
А ведь в этих местах чаще всего прячется технический долг, который больно вылезает через полгода — как только нужно что-то поменять.
Для таких случаев есть инструменты другого уровня. Не про стилистику и правила, а про архитектурную сложность. Один из таких инструментов — jpeek. Он не заменяет линтер, не ругается на System.out.println() и не просит добавить javadoc. Зато он умеет в цифрах показать насколько код близок к объектно-ориентированному аду.
Про jpeek
Как было упомянуто ранее, jpeek — это инструмент для анализа Java-кода, разработанный с акцентом на оценку архитектурной сложности и структурной связности классов. В отличие от линтеров и статических анализаторов, jpeek фокусируется на объектно-ориентированных метриках, таких как сцепленность (cohesion) и связность (coupling), предоставляя разработчикам более глубокое понимание качества архитектуры их кода.
Основной контрибьютор jpeek – Егор Бугаенко. Сам узнал о jpeek после его курса Software Quality Metrics (SQM Crash Course).
Метрики jpeek
jpeek реализует широкий набор метрик, основанных на научных исследованиях и публикациях в области программной инженерии. Вот некоторые из них:
-
LCOM (Lack of Cohesion in Methods) — связность методов внутри класса
-
TCC (Tight Class Cohesion) и LCC (Loose Class Cohesion) — степень связности классов
-
CAMC (Cohesion Among Methods of Class) — степень пересечения списков типов параметров отдельных методов со списком типов всех методов в классе
-
MMAC (Method-Method through Attributes Cohesion) — средняя связность всех пар методов в программе на основе анализа типов параметров и возвращаемых значений
В отличие от SonarQube, PMD и других популярных инструментов, которые фокусируются на синтаксических ошибках, стилевых нарушениях и т.п., jpeek предоставляет глубокий архитектурный анализ, помогая выявить структурные проблемы в дизайне классов, которые могут привести к трудностям при масштабировании системы.
Кроме того, jpeek легко конфигурируется. Благодаря XSL-конфигам, добавление новых метрик или адаптация существующих становится относительно простым процессом.
Аналоги
Существуют и другие инструменты, предлагающие анализ архитектурных метрик:
-
CodeMR — плагин для IntelliJ IDEA, предоставляющий визуализацию метрик, таких как LCOM3, CAMC, LCAM и др.
-
SQMetrics — учебный проект для оценки качества Java-кода с учетом метрик NOC, LLOC, LCOM и др.
-
JProbe — очень древний анализатор (преимущественно для Java EE проектов)
Однако jpeek выгодно отличается своей ориентацией на научно обоснованные метрики, простотой интеграции и возможностью расширения, что делает его ценным инструментом для команд, стремящихся к высокому качеству архитектуры своих Java-проектов.
Пример работы
Для демонстрации я взял небольшой Java-проект — jcabi-http, библиотеку с теми же контрибьюторами, что и jpeek. Проект простой, но с интересной структурой классов, что как раз подходит под анализ архитектуры.
Чтобы подключить jpeek, можно добавить maven-plugin в pom.xml:
<build> <plugins> <plugin> <groupId>org.jpeek</groupId> <artifactId>jpeek-maven-plugin</artifactId> <version>1.0.0</version> <executions> <execution> <goals> <goal>analyze</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
Запускаем:
mvn clean compile jpeek:analyze
После выполнения плагина в папке target/jpeek появятся отчеты — один HTML-файл и один XML-файл на каждую метрику. Также сгенерируется index.html (и index.xml) со ссылками на все метрики.
XML-отчет по метрике CCM выглядит следующим образом:
<package element="false" id="com.jcabi.http.response"> <class color="red" element="true" id="JsonResponse$VerboseReader" value="0.25"> <vars> <var id="methods">4</var> <var id="nc">6</var> <var id="ncc">4</var> <var id="nmp">6</var> </vars> </class> ... </package>
Из отчета видно, что для внутреннего класса JsonResponse.VerboseReader значение CCM=0.25, что говорит о том, что методы класса тривиальны (без условий и ветвлений). В блоке vars содержится следующая информация:
|
Параметр |
Расшифровка |
|
|
количество методов в классе |
|
|
количество вызовов между методами |
|
|
количество связанных пар методов |
|
|
всего возможных пар методов |
Настройка CI
На момент написания статьи jpeek не предоставляет встроенных валидаторов. То есть, он генерирует метрики, но не говорит, что плохо, а что хорошо. Именно поэтому придется писать валидацию самостоятельно, под конкретный проект.
У меня когда-нибудь обязательно дойдут руки написать удобный валидатор для jpeek. Но пока можно обойтись простым питоновским скриптом вида:
import xml.etree.ElementTree as ET import sys # Пороговые значения метрик (определяются эмпирически для проекта) thresholds = { 'SCOM': 0.5, 'LCOM2': 0.3, 'CCM': 0.4 # можно добавить еще метрик } report_path = 'target/jpeek/index.xml' try: tree = ET.parse(report_path) root = tree.getroot() except Exception as e: print(f"Can't read jpeek report: {e}") sys.exit(1) for metric_name, max_defect in thresholds.items(): metric = next((m for m in root.findall('metric') if m.get('name') == metric_name), None) if not metric: print(f"Can't find {metric_name} in report") continue try: defects = float(metric.get('defects', '0')) except ValueError: print(f"Invalid defects value for {metric_name}") continue print(f"{metric_name}: defects = {defects}; maximum value = {max_defect})") if defects > max_defect: print(f"{metric_name} validation failed") sys.exit(1) print("jpeek validation passed successfull")
И дальше из CI можно вызвать:
python3 validate_jpeek.py
Заключение
SonarQube — отличная штука. Он действительно закрывает 90% проверок по качеству кода, распознавая возможные NPE, уязвимости и дублирование кода. Но если хочется получить более подробные и научно обоснованные отчеты, то без метрик вроде LCOM, CAMC или SCOM уже не обойтись.
Именно тут на сцену выходит jpeek — инструмент, который не заменяет привычные линтеры и анализаторы, а дополняет их. Он смотрит не на стиль, не на баги, а на структуру и связность кода.
Интеграция jpeek не требует большого количества усилий. А результаты, которые он дает, вполне можно превратить в часть CI.
Лично я после знакомства с jpeek стал смотреть на архитектуру классов иначе. Попробуйте — это действительно стоит внимания.
ссылка на оригинал статьи https://habr.com/ru/articles/912556/
Добавить комментарий