Многие команды разработчиков в процессе выполнения доработок обрамляют код своими (фамильными) комментариями, а также не забывают оставить предыдущую версию кода в виде комментария. Эти комментарии помогают в любой момент времени понять: кто, когда, по какой задаче и какие изменения внес.
// {begin 03.06.2022 Жу... №10208 }
// Параметры_С.Вставить("НадписьИнфо", строка_ВыгодаПоКарте);
Параметры_С.Вставить("НадписьИнфо", Элементы.ДекорацияИнфо03.Заголовок);
// {end 03.06.2022 Жу... №10208 }
Статья посвящена обратному процессу, то есть, очистке этих комментариев из конфигурации. Интерес к этой статье может появиться у команд, которые перешли, находятся в процессе перехода или планируют переход на EDT + git.
Суть проблемы
Ни для кого не секрет, что в процессе развития бизнеса у программистов появляется все больше и больше задач на доработку. Решение этих задач чаще всего (не всегда) связано с внесением программистами нового кода. Со временем, в результате разработки нового функционала, в системе появляется все больше комментариев. Через несколько лет (или раньше, зависит от размера команды и прыткости каждого ее члена) разработчики начинают терять приличное время на чтение и понимание кода, что отражается на их производительности. Код становится плохо читаем, а скрыть эти комментарии не представляется возможным (в пределах среды разработки).
Польза же от самих комментариев снижается со временем. Есть несколько причин:
Комменты поверх комментов. Разработчики вносят все больше и больше правок, иногда поверх уже кем то доработанного ранее кода. И тут появляется сложность при чтении кода, т.к. надо еще понять, а какой комментарий к чему относится, какой свежее и правильнее. Особенно это касается часто изменяемых участков кода.
Устаревание комментария. Со временем бизнес логика меняется, и изначальный комментарий становится не актуальным для прикладной задачи. При этом разработчику при выполнении доработки приходится читать длинные поясняющие комментарии или закомментированный другими разработчиками код.
Качество самих комментариев. Иногда разработчик оставляет неоднозначные комментарии, над которыми, порой, думаешь дольше, чем над самим кодом.
Большое количество комментариев загромождает код, и сильно отвлекает разработчика от основной задачи - понять, что же этот код делает. Мое самое любимое - это закомментированный запрос в 100500 строк, и следом исправленный вариант запроса. Пока пролистаешь, забудешь о чем шла речь. Еще очень приятно, когда посреди запроса прячутся комменты..
Отрицание
Долгое время наша команда не замечала подобных проблем, пока в один прекрасный день разработчик (привет Геец) не стал жаловаться на сложность понимания кода из за огромного количества комментов. Поинтересовавшись у всей команды, выяснилось, что все испытывают подобную трудность. Терпят и молчат, молчат и терпят. Похоже, нам надо больше общаться..
&НаКлиенте
Процедура ДобавитьВКорзинуФрагмент(ВыбранноеЗначение_ТЗ)
//НовыеСтроки = ПараметрыДанных.НовыеСтроки;
//ПараметрыТовара = ПараметрыДанных.ПараметрыТовара;
// Начало изменений БИТ Пят... И.Н.
// Если Объект.Товары.Количество() = 0 И (Не СуммаСдачи = 0) Тогда
// СуммаСдачи = 0;
// КонецЕсли;
// Окончание изменений БИТ Пят... И.Н.
//ВИТТА_ЛАА_2017-12-05 {
Если ВИТТА_ОптимизированноеПробитие Тогда
//КопияОбъекта = Объект;
//ВИТТА_ДобавитьВКорзинуНаСервере(ВыбранноеЗначение_ТЗ, КопияОбъекта, ПараметрыУказанияСерий, ИдентификаторЧековойСмены, ТекущийПродавец);
//КопироватьДанныеФормы(КопияОбъекта, Объект);
ВИТТА_ДобавитьВКорзинуНаКлиенте(ВыбранноеЗначение_ТЗ);
//Если ТекущаяСтрока <> Неопределено Тогда
// Элементы.РеквизитТаблица.ТекущаяСтрока = ТекущаяСтрока.ПолучитьИдентификатор();
// СтрокаДисплеяПокупателя = Строка(ТекущаяСтрока.Номенклатура);
//КонецЕсли;
Иначе
ДобавитьВКорзинуНаСервере(ВыбранноеЗначение_ТЗ);//ПараметрыТовара, НовыеСтроки);
КонецЕсли;
//ВИТТА_ЛАА_2017-12-05 }
// Если Не ИспользоватьНоменклатуруПродаваемуюСовместно Тогда
// ПодборТоваровКлиентСервер.УстановитьТекстИнформационнойНадписи(ЭтаФорма);
// КонецЕсли;
СкидкиНаценкиКлиент.СброситьФлагСкидкиРассчитаны(ЭтаФорма);
//ВИТТА_ЛАА_2017-12-05 {
Если НЕ ВИТТА_ОптимизированноеПробитие Тогда
БИТ_ЧекККМКлиент.ПересчитатьДокументНаКлиенте(ЭтаФорма, Объект, Истина);
Модифицированность = Истина;
КонецЕсли;
//ВИТТА_ЛАА_2017-12-05 }
// Если добавление товара в корзину производилось при заполненной строке поиска,
// то вернуть фокус ввода на строку поиска.
//ИмяТекущегоЭлементаСтрокиПоиска = ПодборТоваровКлиент.ИмяТекущегоЭлементаСтрокиПоиска(ЭтаФорма);
//Если ЗначениеЗаполнено(ЭтаФорма[ИмяТекущегоЭлементаСтрокиПоиска]) Тогда
// ПодборТоваровКлиент.УстановитьТекущийЭлементСтрокаПоиска(ЭтаФорма);
//КонецЕсли;
КонецПроцедуры
Согласитесь, подобный код читать нелегко. Нужно в коде из 40 строк найти 10 полезных.
Сделал простой опросник на Google Forms для команды разработчиков. Вот, какие результаты мы получили:
Приняли решение обсудить этот вопрос на ретроспективе.
Гнев
На ретроспективе мнения разделились. Некоторым разработчикам эти комментарии казались полезными, кто то без них не может жить (привычка). Большинство посчитало, что основная часть комментариев не несет никакой ценности, и может быть просто уничтожено. Но возник вопрос, а как быть с полезными комментариями?
Нам не удалось принять решение и придти к консенсусу по поводу комментариев. Однако, немного поработав совместно на доске Miro, нам удалось классифицировать комментарии, которыми пользуется команда, накидать предложений (иногда даже безумных) для последующего мозгового штурма, и наметить дальнейший план действий.
Вот что из этого получилось:
Решением по итогам ретроспективы стало
1. Проведение мозгового штурма (к следующей ретроспективе договорились, что каждый разработчик оставит свой стикер с комментариями и мыслями под каждой идеей)
2. К следующей ретроспективе изучаем стандарты в части комментариев, смотрим практику других команд. Назначены ответственные.
Торг
К следующей ретроспективе мы подошли более подготовлено. Изучили стандарты, пообщались с другими командами (в том числе не 1с разработчики), разработчики высказались по идеям на доске Miro:
На картинке не все видно, но суть отражает.
Команды, разрабатывающие приложения не на 1с, так или иначе используют систему контроля версий, и никогда не пишут комментарии по каждой измененной строке кода. Какие-то команды используют удаленные Git репозитории, кто то разворачивает его в компании локально. Для просмотра изменений используют функционал Git (GitLab, GitHub, Bitbucket), некоторые команды считают удобным использование приложений (SMARTGIT и прочие).
В результате длительного обсуждения, прений и разногласий, команда пришла к выводу, что для просмотра истории изменения кода функционала Git + EDT будет достаточно. Главное вносить корректные коммиты, целиком отражающие суть внесенных изменений.
Решения, принятые на ретро:
1) Сносим все (не несущие пользы) комментарии в части кода, который сейчас дорабатывается и будет тестироваться.
2) Добавляем комменты для кода, который будем менять / удалять в будущем (например, после проверки гипотез).
3) Добавляем комменты для кода, который можно интерпретировать неоднозначно. Комментарии, в этом случае, поясняют программисту, почему именно так и не иначе.
4) Оставляем практику описания процедур и функций.
Депрессия
После завершения ретроспективы все разошлись по рабочим местам, и приступили к написанию кода "по-новому", соблюдая договоренности, достигнутые на ретро. Однако, некоторым разработчикам было тяжело изменить манеру написания своего кода, старые комментарии казались очень ценными, их уничтожение казалось невосполнимой утратой. Новые комментарии очень сильно напрашивались. Причина тому - не все до конца понимали, как работают механизмы чтения истории кода в EDT, а разбираться лень и некогда.
Решение пришло достаточно быстро. При слиянии веток видно, что разработчик добавил лишний комментарий. С такими комментарием пришлось поработать, показать разработчику функционал по просмотру истории кода в EDT, и проконтролировать дальнейшие его доработки на наличие коментов.
Принятие
Постепенно команда начала понимать, что вся история сохраняется, ее просмотр не доставляет неудобств и не занимает много времени. При этом код становится чище, и на его чтение тратится меньше времени.
Для приличия, на примере редактирования части модуля посмотрим функционал EDT для просмотра истории изменения кода:
Если ЗначениеЗаполнено(Источник.ВИТТА_Основание) Тогда //по заказу
СтруктураДжСон.Вставить("order_id",Источник.ВИТТА_Основание.НомерПоДаннымКлиента); //Номер заказа
//begin 25.12.2020 ВИТТА Ант... № 835
//СтруктураДжСон.Вставить("add_txn_id",?(Источник.ВИТТА_Основание.ВИТТА_ИсточникЗаказа = Перечисления.ВИТТА_ИсточникЗаказа.Телефон,Источник.Номер,""));//Идентификатор чека
//end 25.12.2020 ВИТТА Ант... № 835
СтруктураДжСон.Вставить("order_total",Источник.ВИТТА_Основание.СуммаДокумента); //Сумма заказа
Иначе
СтруктураДжСон.Вставить("order_total",Источник.СуммаДокумента);
//begin 25.12.2020 ВИТТА Ант... № 835
СтруктураДжСон.Вставить("add_txn_id", Источник.Номер);//Идентификатор чека
СтруктураДжСон.Вставить("client_id", СокрЛП(Источник.Склад.Код));
//end 25.12.2020 ВИТТА Ант... № 835
КонецЕсли;
Убираем комментарии из кода
Если ЗначениеЗаполнено(Источник.ВИТТА_Основание) Тогда
СтруктураДжСон.Вставить("order_id",Источник.ВИТТА_Основание.НомерПоДаннымКлиента);
СтруктураДжСон.Вставить("order_total",Источник.ВИТТА_Основание.СуммаДокумента);
Иначе
СтруктураДжСон.Вставить("order_total",Источник.СуммаДокумента);
СтруктураДжСон.Вставить("add_txn_id", Источник.Номер);
СтруктураДжСон.Вставить("client_id", СокрЛП(Источник.Склад.Код));
КонецЕсли;
В коммите GIT указываем, по какой задаче работали, и что сделано (в примере просто укажу номер задачи). Сливаем ветку в основную. Далее разработчики затягивают эти изменения в свои ветки.
Для просмотра истории кода в EDT команда использует несколько возможностей:
1 способ. Непосредственно в дереве объектов есть возможность открыть историю изменения объекта:
Открывается вся история изменений этого объекта. В истории видим, кто, когда и зачем внес изменения:
С помощью прокрутки увидим сами изменения:
2 способ. В контексте самого модуля можно сразу видеть какие строки были изменены. Для этого надо щелкнуть правой кнопкой мыши на левом поле редактора и выбрать пункт "Показать информацию о редакции". В этом случае, EDT начнет выделять цветом измененные строки прямо в редакторе:
На полях появятся подкрашенные номера строк, что свидетельствует о том, что можно посмотреть историю изменений.
При наведении мышкой на подкрашенную строчку, можно перейти к истории.
Можно открыть информацию, и прокрутить к нужной строке. Снова наводим мышь на подкрашенное поле, EDT покажет, что было изменено.
Замечу, что все изменения так же можно найти в любой системе контроля версий. Как бы, для этого они и предназначены.
Написание этой статьи спровоцировано отсутствием подобной информации (по крайней мере, мы не нашли за короткое время). Нам бы она помогла в свое время. Надеюсь, она будет полезна тем командам, которые столкнутся с подобной проблемой.
Вот так, по простому о сложном или сложно о простом, кому как зайдет.
Основной вопрос, который у меня возникает: как измерить эффект от этих изменений, дать оценку. Насколько улучшилась читаемость кода, на сколько ускорилась разработка? Пока планирую собирать обратную связь от программистов. А что думает сообщество?