Анализ зависимостей программно? NDepend!

понедельник, 14 февраля 2011, Роман Калита

Как поддерживать качества код на должном уровне? Есть много способов – культура написания кода, регулярное code review, всевозможные договорённости внутри команды (convensions), парное программирование и прочие практики XP, TDD, BDD, DDD… Список можно продолжать, и в него будут попадать все более страшные слова :) Но на самом деле каждый выбирается для себя свой способ.

А как следить за качеством кода в большой команде или нескольких команд? А если вы ими руководите и не можете уследить за всем кодом, т.е. участвовать в его написании, или кода настолько много что его ревью отнимает много времени? Тут нужно что-то придумать. Нужна лакмусовая бумажка которая укажет нам какие участки большой code base пересматривать а какие можно упустить. Такой лакмусовой бумажкой могут стать утилиты статического анализа и метрики кода. Тогда, по метрикам кода можно определить участки требующие внимания.

А одна из таких утилит, достаточно навороченная, с возможностью просматривать большое число метрик – NDepend. Помимо всего прочего основной акцент NDepend – это анализ зависимостей, поэтому прежде всего он поможет для анализа и разрешения проблем с зависимостями в коде.

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

И тут вступает в игру одна из самых красочных фич NDepend – Граф зависимостей (dependency graph).

image

Причем смотреть зависимости можно между сборками, типами, методами и т.п.

image

Линии между блоками имеют определенное значение и если навести на них можно получить описание. Например зависимость между классами Step и Workflow которые показаны на Графе зависимостей на картинке выше.

image

Причем тут следует сказать что NDepend работает как с solution файлами так и со сборками, поэтому можно анализировать сборки даже без исходного кода.

Еще одним графиком который умеет отображать NDepend – матрица зависимостей (dependency matrix)

Матрица зависимостей это другой вариант представления зависимостей между элементами кода. Она находиться в синхронизируемом состоянии с графом зависимостей.

image

Например на матрице зависимостей мы видимо такую метрику как dependency cycles в виде красных квадратов. Что за метрика можно посмотреть также в контекстной помощи.

image

Еще один визуализатор – это Метрики (Metrics)

Он просто визуализирует метрики кода в виде такой вот матрицы:

image

Между метриками можно переключатся и соотвественно определять наиболее большой элемент. Например если нас интересует количество строк код то нам небходимо выбрать метрику lines of code (LOC) и проанализирвоать самые большые по площади элменты матрицы метрик.

CQL (Code Query Language)

В NDepend включена такая фича как CQL. CQL – это похожий на SQL синтаксис для того чтобы делать запросы на анализируемый код и получать на выходе результат в виде соответствия или не соответствия метрик.

Например, запрос на картинке ниже выводит не используемые типы:

image

CQL полезен для написания собственных запросов на анализируемый код. Но NDepend содержит большой набор уже построенных запросов. На основании которых он выводит определенные рекомендации к коду.

На картинке ниже показаны запросы которые отработали на анализируемом кода, например есть неиспользуемые методы и типы.

image

Интересно также что NDepend может проверять покрытие, это если мы анализируем solution из Visual Studio:

image

Или запросы связанные с производительностью, в данном случае boxing/unboxing и размер объектов:

image

В NDepend можно просто и быстро строить новые запросы на CQL, например простенький запрос на картинке ниже:

image

Метрик, которые анализирует NDepend, очень много и сразу наверное все не понять. Но к примеру может помочь этот постер про метрики кода (взят отсюда, картинка кликабельная и можно загрузить):

image

Из наиболее полезных метрик можно выделить, кроме привычных нам по типу Lines of Code:

  • Afferent coupling (Ca) Метрика описывает число типов или методов из внешних сборок, которые используют заданный тип или метод. Чем выше это значение – тем важнее заданный тип или метод  для внешней сборки.
  • Efferent coupling (Ce) Прямая противоположность Ca: описывает число внешних методов и типов сборки, которые использует определенный тип или метод. Чем выше значение, тем более зависимый указанный тип или метод от внешней сборки.
  • Relational cohesion (H) Метрика описывает насколько сильно соотносятся типы внутри одной сборки. Обычно, типа внутри сборки могут быть сильно связаны, но не ооочень сильно (всему есть придел).
  • Instability (I) Описывает насколько чувствительна определенная сборки относительно изменения в зависимых сборках. Измеряется как частное от efferent coupling (Ce) и total coupling (Ca+Ce).
  • Abstractness (A) Описывает соотношение абстрактных типов в сборке.
  • Distance from main sequence (D) Нестабильность (І) и абстрактность (А) должны быть сбалансированы. Другими словами сборка с высокой степеью абстрактности должна быть стабильной, так как она скорее всего используется другими сборками. Если сборка нестабильна (I), то скорее всего рано или поздно  в нее будут внесены изменения и это повлечет собой необходимость вносить изменения в зависимые от нее сборки. С другой стороны, от от более “конкретной” сборка чаще всего не зависят другие сборки, в так случае допускается нестабильность (I) сборки в той или иной степени.
  • Lack of cohesion (LCOM) В связанных классах большинство методов имеют дело с членами таких классов. Если окажется что большинство методов класса работают только с какой то частью методов связанных классов – это может стать индикатором того что ответственность (responsibility) класса слишком широкая и нужно произвести его декомпозицию (например разбить на классы).
  • Cyclomatic complexity (CC) По этой метрике есть статья в википедии написанная сложным языком :) Можно понимать ее как анализ вложенностей метода. Описывает сколько возможных ветвлений и вложенностей, циклов, имеет метод. Метод с высоким CC сложно поддерживать.

Еще можно посмотреть определения всех метрик на сайте NDepend.

NDepend интегрируется с билд процессом – TFS, Cruise Control.NET, FinalBuilder, TeamCity. Для этого есть документация на сайте. Также есть консольный вариант. Так что автоматизируется задачи NDepend – “на ура”. Также в конце билда или анализа кода NDepend предоставляет сводный HTML отчет.

У NDepend есть возможность интегрироваться с Visual Studio 2008, 2010 (и наверное 2005, не проверял). Но к сожалению на загрузку дается только zip архив со всем необходимым. Мне кажется что им стоит все таки сделать простенький msi инсталлер и давать пользователю на выбор что загружать архив или его.

Также для NDepend есть определенный порог входа, и он достаточно не низкий. Метрик, графиков достаточно много и нужно уметь в них разбираться, анализировать и принимать решения. Для обучения на сайте есть неплохая документация, но к сожалению с “инсталляцией” самого продукта она не идет. Я думаю также можно найти подкасты или вебкасты в интернете. Например есть неплохое видео демо и туториал – Getting started

NDepend продукт не бесплатный, его стоимость порядка 400$ на 2 разработчика, и порядка 600$ на 2 билд компьютера. Это не дешево, поэтому каждому разработчику такой продукт не поставишь. К тому же в Trail/Open source/Academic лицензиях нет возможности зумирования на Графике зависимостей что весьма достает и делает анализ сложных и больших проект очень сложным. Мне бы хотелось чтобы зумирование разрешили в этих лицензиях.

NDepend продукт с достаточно захватывающими возможностями. Причем его сила не только в визуальной стороне. Визуальные графики – скорее для быстрого охвата и просмотра, а вот интеграция с билд процессом, и результаты CQL, и метрики покажут на что смотреть. Но малым командам, или индивидуальным разработчикам , или тем у кого небольшая code base такой продукт наверное не нужен – слишком дорог для этого. А вот большим командам, возможно с одним или несколькими архитекторами и большой code base – он пригодится. В таком сценарии визуальная часть устанавливается на компьютеры архитекторов плюс обязательная интеграция в билд процесс для остальных участников команды.


Ищите нас в интернетах!

Комментарии

Свежие вакансии