Чистый код — чистая совесть. Война с клонами кода

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

Чем опасны клоны кода

На первый взгляд, клоны кодов не кажутся большой проблемой. Например, если рассмотреть данную проблему с точки зрения производительности приложения, то влияние клонов на нее сводится только к увеличению объема кода, что влечет за собой «раздувание» конечного приложения в собранном виде. Такое «раздувание» грозит дополнительным объемом RAM, необходимым для запуска приложения. Если не вдаваться в крайности (когда 90% вашего кода — бесполезные клоны), то в целом, клоны слабо влияют на конечную производительность приложения.

Но есть и обратная сторона медали: клоны могут негативно влиять на продуктивность вашей работы, как это не странно:). Рассмотрим эту проблему с точки зрения удобства поддержки и развития приложения. Если в вашем приложении есть клоны, то в случае изменения функционала или исправления ошибок, которые затрагивают работу с этими клонами, разработчику необходимо вносить одни и те же изменения. Если разработчик знает, куда в данном случае вносить изменения — это хорошо. А если нет?

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

Так вот, о влиянии на продуктивность работы. Представим себе, что в команду прилетает какой-то баг, связанный, ну к примеру, с тем, что приложение на сервере не может получить доступ к какому-то файлу (из пальца высосал пример, но тем не менее). Прилетает этот баг на тимлида, который перенаправляет решение этой задачи на вас. Вы, зная, что в вашем функционале используется этот файл, пишете правку в методе, который работает с этим файлом, и с чувством выполненного долга отдаете это исправление на тесты. На следующий день вы получаете результаты тестов и с удивлением обнаруживаете, что на сервере все равно возникают ошибки при работе с этим файлом. Оказывается, что ваши исправления только частично решили проблему, так как есть клон, который не был исправлен. Итог: вы потеряли день, а баг не исправлен полностью. Как это повлияло на бизнес? День некорректной работы приложения легко запапить на финансовые потери, недополученную прибыль.

Поиск клонов с помощью Source Control

Решение этой проблемы достаточно простое. Прежде чем запускать сборку и публикацию приложения, проверьте код на наличие клонов. А чтоб не делать это руками, можно выгрузить последнюю версию кода из Source Control и в Visual Studio запустить анализатор кода на наличие клонов:

В результате вы получите табличку с обнаруженными клонами, разгруппированную по блокам Exact Match, Strong match, Middle match, Weak match. В моем случае получилось так:

Выделив два предполагаемых клона можно вызвать контекстное меню «Compare» для просмотра клонов:

Результат отображается в виде Diff-а:

Найденный клон является хорошим кандидатом для рефакторинга.

Механизм работы

Теперь немного о том, как это происходит поиск:

Pre-processing — на этом этапе код партиционируется, и определяется область поиска. Есть три основных цели этого этапа:
— Удаление не интересующих частей кода для поиска клонов. Например: разделение кода по языку программирования;
— Определение source units. Это разбиение кода на несвязанные куски;
— Определение кусков кода для сравнения. Производится над найденными source units.

После этого следует Coarse Matching — трансформация найденных кусков кода для сравнения в вид, удобный для сравнения.

Затем происходит Fine Matching — устранение явных совпадений, типа пробелы, комментариев и т.п.

И, наконец, Pruning — на этом этапе запускается алгоритм поиска клонов и идет ранжирование результатов.

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

Применение программы

Для того, чтоб механизм поиска клонов искал их там, где нужно, его нужно настроить. Идея состоит в том, что, есть стандартные куски кода, например, инициализации окна в WPF, которые не нужно включать в результат поиска клонов. Настройка осуществляется путем подбрасывания в наш проект файла с расширением «.codeclonesettings», в котором мы определяем исключения.

Ниже пример такой настройки:

У данного движка есть ряд ограничений:

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

— В поиске участвуют только инструкции (statements) внутри методов и определении свойств.

— В поиске не участвуют метода, количество инструкций в которых меньше 10. Но если очень хочется, можно поискать клоны конкретного выделенного куска кода:

— В поиске не будут отображены фрагмента с разность более 40%.

— В поиске не будут отображаться исключения, заданные в файле «.codeclonesettings».

Советы по применению данного движка:

— Применяйте анализатор ко всему вашему Code Base. Если ваш проект разбит на несколько Solution, создайте отдельный Solution, который включает все проекты.

— Если вы применяете T4 транформации либо другие способы автоматической генерации кода, исключайте их из анализа путем прописывания в файле «.codeclonesettings» соответствующих настроек. Например, для T4 можно сделать следующее: все сгенерированные файлы складывать в директорию «GeneratedFiles» вашего проекта. А в «.codeclonesettings» исключить эту директорию из поиска добавив " GeneratedFiles\*.cs «.

— Запускайте анализатор во время изменения\добавления существующего кода или во время плановой «зачистки» кода.


Если есть вопросы, я всегда готов ответить в комментариях.

Все про українське ІТ в телеграмі — підписуйтеся на канал DOU

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn



18 коментарів

Підписатись на коментаріВідписатись від коментарів Коментарі можуть залишати тільки користувачі з підтвердженими акаунтами.

Ви все ще копіпастите код? Тоді ми йдемо до вас! :)

А яким ще чином можуть появитися «клони»? Дві різні людини не можуть написати однаковий код — тому такий аналіз не захистить від того, що хтось чогось не знайшов і написав заново. А якщо хтось накопіпастив код — ну ... напевно для цього була причина.

Ви все ще копіпастите код?
навскидку
независимое написание парсинга одной и той же структуры в разных местах проекта
функции-коллбеки в map/filter/reduce применительно в данным схожей структуры
хендлеры асинхронных событий(если разные события должны приводить _примерно_ к одному и тому же результату)

хороший инструмент. если бы еще студия к ресурсам так требовательна не была бы.

в Inteliji IDEA тоже есть свой инструмент: Analyze->Locate Duplicates
интерфейсно выглядит получше: выбираешь область поиска(путь + набор файловых масок — настраивается для проекта как «Scope» не только для анализа дубликатов, но и для поиска, например), выбираешь языки программирования(привязка ЯП<->расширения задаются отдельно), задаешь несколько параметров для анализа(anonymize literals + anonymize expressions + anonimize small functions — дает тот самый диапазон от strong match/equal до similar) и вперед

однако проблема — анализ текстовый. не помогает в случаях, когда порядок строк не имеет значения(правила в пределах CSS селектора, элементы хеша в JSON, XML если мы уверены, что порядок узлов не важен).

зато проверялку из VS, наверное, можно к CI прикрутить. да?

К сожалению пока нет, но видимо вопрос актуален: visualstudio.uservoice.com/...on-to-be-run-from-command

зато проверялку из VS, наверное, можно к CI прикрутить. да?
это сейчас проблема разве? CI и так ищут дубликаты еще и в код прямо тычут девелопера где их исправлять.
лучше привели в порядок navigate to... переписывание студии никак не улучшило ситуацию с типичными проблемными куда более часто используемыми девелоперами IDE фичами.
это сейчас проблема разве?
для меня нет — бо использую Inteliji
обсуждаю фичу
насколько она нужна, особенно в версии интеграции в CI для, например, сишников — без понятия
лучше привели в порядок navigate to
R# в помощь.

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

Незачем. Я пользуюсь VS Professional + R# Ultimate и всем доволен. По сути можно перейти на Community Edition, но Code Lens интересная штука. Кстати, уже можно пробовать Project Rider.

то ли дело, если node.js — твой рантайм. «jsinspect .», пару сотен миллисекунд и репорт по копи-пасте (причем по семантике тоже, не только по тексту) готов. само собой 0 усилий, чтобы прикрутить к CI/CD. github.com/danielstjules/jsinspect

Ради такого безусловно надо завести отдельный топик xD

а че б и нет?
тем более, если верить гуглу, уникальный.
и реклама, и полезность, и повод для срача, если кто захочет.
со всех сторон — профит

Не такой уж и уникальный

msdn.microsoft.com/...-ru/library/hh205279.aspx

ну, когда я писал, пробовал искать по паре фраз. первой ссылкой было DOU, MSDN в списке отсутствовал

И как, есть саксес-стори использования этого дела от разработчиков за пределами Майкрософта? :)
PS. не ведитесь на этот коммент, далее последует очень толстый троллинг пресловутой компании.

есть саксес-стори использования этого дела от разработчиков за пределами Майкрософта
это вы ща про VS в целом?

Підписатись на коментарі