При непрерывной итерации неизбежно возникают схожие бизнес-требования к проектам. Каждый дизайнер-разработчик наверняка сталкивался с подобной ситуацией. Зачастую аналогичные реализации приводят к тому, что функции или компоненты с одинаковыми функциями копируются и используются напрямую. Корень проблемы обычно заключается в спешке при разработке требований к управлению проектами. Сроки, выделяемые на этот процесс, предельно сжаты.
Длительное накопление дублирующегося кода приводит к тому, что каждый последующий проект становится все сложнее обслуживать. Объем проекта с дубликатами существенно увеличивается, а читаемость ухудшается.
С другой стороны, замена одного и того же кода во многих местах при исправлении или расширении функционала — дорогое удовольствие. Большие затраты на исследования и разработку в конечном итоге еще больше затрудняют обслуживание проекта. Таким образом, дублирование кода в определенной степени влияет на общее качество проекта.
Обнаружение повторяющегося кода — важнейший момент в системе построения качественной инженерии. Поэтому стоит поговорить том, как выявлять и устранять участки-клоны в фронтенде проекта.
Пример
Для наглядности рассмотрим простейший пример. Предположим, что в проекте React есть две страницы: about page
(О проекте) и home page
(Главная). Обе включают компонент table
с одинаковыми функциями. Код представлен ниже:
// about page
import React from 'react';
export default () => {
console.log('this is about page');
return <>
<table border="1">
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
</table>
this is about page
</>
}
Как видите, на странице about page
есть компонент table
. Он также находится и на главной странице (home page
).
// home page
import React from 'react';
export default () => {
console.log('this is home page');
return <>
<table border="1">
<tr>
<th>Month</th>
<th>Savings</th>
</tr>
</table>
this is home page
</>
}
Как выявлять дублирующийся код
Сообщество открытого ПО разработало проект с открытым исходным кодом под названием jscpd, который поддерживает возможность обнаружения дублирующегося кода. Адрес на GitHub.
Посмотрим, как jscpd справляется с этим. Как правило, в инженерной системе серия атомарных сервисов образует целое инженерное звено обнаружения. Реализация каждого атомарного сервиса представляет собой реализацию скриптов. Это могут быть скрипты Node, Python и т. д. Вам не нужно беспокоиться о конкретной реализации технологического стека до тех пор, пока функция может быть реализована. На примере приведенных выше страниц познакомимся с двумя способами использования jscpd для обнаружения дублирующегося кода.
Первый способ — ввод команды sell
непосредственно в консоль. Для этого способа необходимо установить зависимости jscpd глобально с помощью команды npm i -g jscpd
. После завершения установки можно перейти к корневому пути проекта React и выполнить следующую команду:
jscpd -p "src/**/*.js" -k 15 -l 5
Вот что означают параметры выше.
-p
— регулярное сопоставление всех файлов по шаблону glob (тогдаsrc/**/*.js
— это обнаружение всех файлов с суффиксом js в каталогеsrc
).-k
— минимальное количество повторений токенов в тегеcode
(можете понимать токен как слово, здесь оно установлено на значении 15, тогда фрагмент кода будет обнаружен, только если он содержит 15 слов или более).-l
— минимальное количество строк кода, которые должны быть обнаружены (здесь установлено значение 5, то есть обнаружение будет производиться только для кода, содержащего более 5 строк).
Чтобы увидеть больше параметров, выполните jscpd -h
в командной строке. Результат выполнения показан на изображении ниже:
Как видите, в итоге обнаружен дублирующийся код в двух файлах, в общей сложности 8 строк и 56 токенов.
Повторяющийся код может быть компонентом, функцией или классом. Существует множество ситуаций дублирования, поэтому каждый конкретный клон должен быть проанализирован соответствующим образом.
Заключение
Обнаружение дублирующегося кода — необходимая часть качественного проектирования. Пренебрежение этой проблемой чревато снижением читабельности проекта и усложнением его обслуживания. Обобщив все вышесказанное, выделим основные моменты.
Инкапсуляция компонентов — это как раз то, что подходит для приведенного выше примера. Для подкомпонентов, использующих одни и те же функции в нескольких компонентах, следует рассмотреть возможность инкапсуляции этих самых компонентов в публичные. Тогда при использовании других компонентов можно будет напрямую обращаться к публичным. Это также сделает обслуживание более удобным. При изменении компонентов публичные могут быть изменены единообразно.
Извлечение функций — это, говоря простым языком, извлечение одинакового модуля реализации в функцию, что удобно для повторного использования. Если речь идет об одинаковых функциях, их можно извлечь напрямую. Если две функции не одинаковы, можно отделить одинаковые части от других, извлечь одинаковые части в функцию, а различные части оставить.
Продвижение метода — еще один способ устранения дублирующегося кода. Используется в тех случаях, если есть похожие реализации в нескольких подклассах. Тогда можно продвинуть метод в родительский класс для унифицированной реализации, при которой каждый подкласс наследует данные один раз.
Читайте также:
- 5 советов о том, как улучшить комментарии в коде
- Трассировка стека и более точная отладка
- Плюсы и минусы парного программирования
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи omgzui: How to Detect Duplicate Code in a Project?