5 недостатков кода, из-за которых его сопровождение превращается в ад

27.04.23

Разработка - Рефакторинг и качество кода

О сопровождаемости кода. Коротко и в легкой форме. Какие проблемы с кодом бывают, как их решать.

 

Любой дурак сможет написать код, который поймет машина. Хорошие программисты пишут код, который сможет понять человек. (с) Мартин Фаулер, автор книг и статей по архитектуре ПО

Кто-то может спросить, о чем вообще речь в этой цитате, и почему так важно писать код, понятный человеку. Если кратко: программист 1С (и не только) больше времени тратит на чтение кода, нежели на его написание. 

Если код сложно читать и понимать, то и накосячить в нем проще простого, и развивать его сложнее, дольше и дороже. О самых запущенных случаях и говорить не хочу – из-за них спецы чувствуют себя как в аду, и быстро выгорают. 

Ниже мои топ-5 огрехов разработчика, из-за которых работа с его кодом становится сродни катастрофе.

1. Нестандартное (или отсутствующее) форматирование кода. Проблемы с оформлением бывают в основном у новичков. Некоторые придумывают свой уникальный стиль, не зная, что есть готовые стандарты. Другие вообще не заморачиваются с оформлением. 

Итог: читать этот код нужно особенно внимательно. И постоянно задаваться вопросами вроде «где я – в цикле или в какой-то ветке какого-то условия?»/ «а в этой длинной строке одна операция или еще 10?»

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

Хорошая новость: отформатировать код можно автоматически (инструментов для этого много, расскажу о них в другой раз).  

Плохая новость: если отформатировать изначально плохой код, он не станет внезапно хорошим.

2. Непонятные названия процедур, функций, переменных. Такой грех водится и за опытными разработчиками. Придумать краткое и емкое имя переменной порой сродни мукам поиска заголовка для статьи. Проще написать первое, что пришло в голову. В лучшем случае оставить рядом поясняющий комментарий. Но это если настроение есть.

Итог: при чтении кода с непонятными именами приходится постоянно прыгать от вызова функции к ее описанию, чтобы понять, что она выдает. Или от места использования переменной к месту присвоения ей значения, чтобы понять, что она хранит. Это, опять же, отнимает время и силы.

Что делать: практиковаться в придумывании имен и не жалеть на это времени. Задавайтесь вопросом – что конкретно делает эта процедура или хранит переменная. Если хорошее имя есть, код станет понятен без комментариев. А учитывая, что в 1С программируют по-русски, его можно будет читать как документацию. 

Хорошая новость: возможно, в непростом деле придумывания имен нам вскоре смогут помочь нейросети.

Плохая новость: но это не точно.

3. Велосипедостроение. Под этим я подразумеваю героическое решение задач, которые давно решены другими. Или внесение доработок авторским способом, когда в компании уже есть сложившаяся практика на этот счет или даже регламенты. 

Итог: другим приходится тратить время и разбираться в наработках и приемах автора кода «с велосипедами».

Что делать: разрабатывать и внедрять регламенты, стандарты, и заставлять разработчиков им следовать. 

Хорошая новость: у 1С есть готовая система стандартов разработки прикладных решений, библиотека стандартных подсистем (БСП). 

Плохая новость: если разработчик любит изобретать велосипеды, то он будет их изобретать несмотря ни на что.

4. Трюкачество. Это необычные приемы программирования, которые усложняют решения даже простых задач. Часто трюки используют для оптимизации или для сокращения объема кода. Но если в первом случае это еще может быть оправдано (далеко не всегда!), то во втором – это просто намеренное вредительство. 

Итог: чтение и доработка кода с трюками – то еще удовольствие, ошибки обеспечены. 

Что делать: перечитывать код, задавая себе вопрос – «а разобрался бы с этим джун Вася из соседнего отдела?» Если ответ – «вряд ли», лучше код переписать.

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

Плохая новость: если трюки в коде разработчика получаются вопреки его желанию — ему точно есть куда расти.

5. Возведение монолитов. Хорошая программа состоит из отдельных, слабо связанных между собой элементов. В этом случае с ней проще разобраться – не нужно «есть слона целиком», он уже разделен на части. А отдельные элементы можно переиспользовать для решения других задач. Но разрабатывать такие программы сложнее – требуется навык правильной декомпозиции задачи на составляющие. И навыку этому нельзя просто где-то научиться, он приходит только с опытом. Поэтому у неопытных разработчиков решение большой задачи часто выливается в монолитный код с кучей внутренних связей. 

Итог: дорабатывать и исправлять такой код опасно. Починишь в одном месте – сломаешь в трех других. А чтобы добавить новый функционал – приходится менять уже существующий и хорошо работающий код. 

Что делать: привлекать опытного специалиста, хотя бы для проектирования решения и проверки кода разработчика. А разработчику – набираться опыта, изучать код других, читать книги по методологиям разработки ПО. 

Хорошая новость: опытные спецы есть, их на рынке много. 

Плохая новость: они стоят дорого 

Лучшее средство для искоренения всех перечисленных проблем – ревью кода. Программист постарше изучает код коллег и вершит над ними страшный суд дает им советы о том, что и где нужно исправить. Да, в 1С это мало кто делает. Да, это трудоемко. И да, это дорого. Но поверьте – некачественный код в конечном счете обходится дороже. 

В комментариях предлагаю поделиться вашими методами борьбы за качество кода. Или рассказать о том, какие огрехи в коде – ваша личная боль. У меня, например, с наименованиями пока бывают сложные отношения. Сегодня имя кажется хорошим, а через неделю, возвращаясь к коду – уже не понимаю, что я имел в виду под этим именем. :)

См. также

Результаты ревью кода 1500+ решений каталога Инфостарт: наиболее частые ошибки разработчиков в коде

Рефакторинг и качество кода Платформа 1С v8.3 Бесплатно (free)

Поделюсь своим опытом аудита кода авторских продуктов с Infostart.ru как одним из элементов применения DevOps-практик внутри Инфостарт. Будет настоящий код, боевые скриншоты, внутренние мемы от команды ИТ-лаборатории Инфостарт и прочее мясо – все, что любят разработчики.

10.04.2024    6379    artbear    83    

79

Ниндзя-код

Рефакторинг и качество кода Платформа 1С v8.3 Россия Бесплатно (free)

Предлагаю вашему вниманию советы мастеров древности. Программисты прошлого использовали их, чтобы заострить разум тех, кто после них будет поддерживать код. Гуру разработки при найме старательно ищут их применение в тестовых заданиях. Новички иногда используют их ещё лучше, чем матёрые ниндзя. Прочитайте их и решите, кто вы: ниндзя, новичок или, может быть, гуру? (Адаптация статьи "Ниндзя-код" из учебника JavaScript)

01.04.2024    2412    DrAku1a    15    

33

Практическое программирование: когда скорость важнее совершенства

Рефакторинг и качество кода Бесплатно (free)

В новом материале мы анализируем, как в программировании баланс между быстротой разработки и тщательной проработкой кода влияет на конечный продукт. Обсуждаем, почему иногда важнее сосредоточиться на скорости выполнения проекта, и когда можно позволить себе уступить в качестве ради достижения бизнес-целей.

01.04.2024    632    Prepod2003    6    

2

Когда понадобился новый оператор

Рефакторинг и качество кода Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Когда понадобился новый оператор, но его нет в синтакс-помощнике, что делать?

18.03.2024    1373    ZhokhovM    4    

4

Когда разработчик платформы не добавил проверку препроцессоров

Рефакторинг и качество кода Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Когда разработчик платформы решил пойти на кухню за кофе, а проверку препроцессоров не добавил, и вот тут-то и началось: "Что, опять все сломалось? Ну и кофе же я забыл сделать!".😅

18.03.2024    3044    ZhokhovM    4    

9

Реструктуризация - бесконечная история

Рефакторинг и качество кода Платформа 1С v8.3 Бесплатно (free)

При разработке программ требуемый функционал ставят на первое место, но есть еще и архитектура программы. На горизонте 5-10 лет она становится важнее функционала, который должен работать при масштабировании и росте данных. Реструктуризация 5 терабайтной базы 1С 8.2 в формат 1С 8.3, складывает весь пазл архитектурных просчетов, которые сделали ради функционала. Как это исправить? - для разработки правильной архитектуры, нужно всего лишь сместить фокус с функционала и подумать о «вечном».

29.09.2023    2107    1CUnlimited    15    

23
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. ixijixi 1801 27.04.23 12:46 Сейчас в теме
С переменными да, есть проблема)
По трюкачеству не очень понял. Порой без трюков не обойдешься, вот свежий пример
Прикрепленные файлы:
kaaasteeen; maksa2005; wonderboy; 0x00; +4 Ответить
5. fishca 1255 27.04.23 13:48 Сейчас в теме
(1) так ведь в статье речь о трюкачестве в коде, а не в настройке 1с
12. ixijixi 1801 27.04.23 14:25 Сейчас в теме
11. wonderboy 379 27.04.23 14:23 Сейчас в теме
(1) Да, в 1С без трюков не всегда получается, нет в мире совершенства :)

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

Из реальной жизни мне часто попадается на ревью такое:
Есть несколько условий в коде. И я вижу, что не учитывается какое-то конкретное условие, и выполняется ветка кода, которая по логике выполняться в этом случае не должна. Но код в той ветке написан так, что в итоге к проблемам это не приводит. Все работает вроде бы и правильно. Но чтобы в этом убедиться - пришлось серьезно поднапрячь мозги при ревью. Хотя ведь можно было написать еще одно условие в блоке "Если", и сделать код более логичным, чтобы вот в данном конкретном случае этот код просто так не выполнялся.
надеюсь не очень путано и смог донести мысль :)
Рамзес; +1 Ответить
2. Serg O. 263 27.04.23 13:34 Сейчас в теме
Вы пишите: Хорошая программа состоит из отдельных, слабо связанных между собой элементов.

Дайте конкретное определение - Что такое " слабо связанных между собой элементы" ? про какие "элементы" вы говорите?
элементы - это что ? процедура, функция, элемент метаданных типа справочник или документ ?
Как именно определить и желательно в числовом выражении эту "слабо-связанность" ?

И вы не видите (не говорите о её возникновении) о другой стороне проблемы:
- При разделении на "слабо-связанные" элементы - растёт количество таких связей и внешних вызовов.
(число таких связей расчет со временем в геометрической прогрессии! и "связность" разных "элементов" только расчёт! )

Как посчитать число связей (если это вообще возможно) - и как определить слабо-связаны они или сильно-связаны ?
например, Есть конкретная оценка - "цикломатической сложности" - это число.
если код перенести в Visial Studio Code - она считается там сразу, (если добавить расширение - Language 1C (BSL) )
и в некоторых функциях (даже типовых) оно легко зашкаливает за 100-200+ при норме в 5-10

Есть ли такая же оценка (желательно автоматическая) для "слабо" или "сильно" связанных элементов или модулей ?
из чего-то подобного видел только обработку для "рисования" связей между реквизитами справочников-документов, а не для кода.

Кроме того множественность вызовов порождает "матрёшки"
Когда чтобы добраться до кода, надо 5 и более вызовов друг друга разных функций просмотреть ... да ещё и раздвоение - растроение на каждом уровне... т.е. получим от 2^5 (32) до 3^5 (243) функций которые надо "просмотреть" !
это по-вашему "хороший" код, который отлаживать практически невозможно?

1С похоже уже пошло по пути такого разделения - каждый из модулей ещё разделён на разное выполнение:
Сервер / Клиент / КлиентСервер и ещё ПовторногоИспользования ... так же умножаем на 3 варианта
- и получаем 6 модулей вместо одного...
----------------------------------------------------------------------------------------
видно, что перечислены только несколько признаков "плохого кода" ... и не для 1С, а "вообще" ...
из какой-нибудь книжки Роберта Мартина ... например, или с сайта рефакторинг - "запахи плохого кода" ...

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

конкретных инстументов или чего-то полезного в статье не видно
TerveRus; dooD1iez; Demetry2000; badday; +4 Ответить
9. wonderboy 379 27.04.23 14:10 Сейчас в теме
(2) Ух, спасибо за большой развернуты комментарий!

Цель моей публикации - обратить внимание на признаков "плохого кода", которые мне видятся наиболее часто встречающимися. Причем коротко, т.к. многим сейчас (не всем, конечно!) читать длинные тексты некогда. Поэтому да, без примеров, без инструментов. Но я считаю самый надежный инструмент здесь - это анализ кода квалифичированным спецом.

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

Про цикломатическую сложность - это вы верно упомянули, хорошая формальная мера сложности кода.

"При разделении на "слабо-связанные" элементы - растёт количество таких связей и внешних вызовов"

А вот это зависит от архитектуры, которую придумал разработчик. Взять к примеру ООП. Для чего его вообще придумали? Как раз для того, чтобы бороться со сложностью ПО. Объет представляет собой некую замкнутую сущность с небольшим (в идеале) количеством публичных методов. И это позволяет рассматривать объект отдельно от остального кода проекта. А в рамках более крупных блоков - уже рассматривать взаимодействие объектов, без необходимости погружаться в детали их реализации.
Вот об этом речь в "монолитах", о которых я говорю. Это когда у разработчика не получается выделить такие независимые сущности в коде, которые можно изучать отдельно от кода всего проекта.
Рамзес; Serg O.; +2 Ответить
13. Serg O. 263 27.04.23 14:59 Сейчас в теме
(9) цель хорошая... привлечь внимание к "хорошему коду"
тогда уж надо было добавить один из базовых принципов - DRY (Don't Repeat Youseft - принцип "сухости" кода)
потому как многие (и не только начинающие!) программисты "грешат" повторением кода или copy-past вставками даже внутри одной процедуры...
- для оценки и контроля уровня "копи-паста" уже есть инструменты - внешние обработки на Инфостарте (одну из них я сам переделывал)

пример с объектами ООП ... как бы не совсем для 1С ... ООП официально в 1С как-бы нет (ну или почти нет)
и это не решает проблему "слабо-связанных элементов" ...

Скорее тут подходит что-то в духе термина "Устойчивости" из книги Роберта Мартина "Чистая архитектура"
где дана конкретная методика определения "метрики устойчивости" (число от 0 до 1 - точнее термин неустойчивости Instability)...

Метрика считается достаточно просто: число исходящих вызовов и ссылок на другие элементы
(объекты метаданных или модули/процедуры/функции/...),
делённое на общее число связей (исходящих и входящих) этого элемента.
то есть есть конкретная формула "нестабильности" I = N out / (N out + N in)
например, Общая функция, которая ни на кого не ссылается, а только её все вызывают - максимально стабильна (I = 0)
и наоборот Документ, например Реализация - который состоит из множества ссылок на Контрагента, Договор, таблицу Номенклатуры и т.д.- нестабилен (метрика I стремится к 1) - множество внешних связей и почти нет ссылок на этот объект в других объектах.

так вот - введение "слабо-связанных элементов" - это термин который любят сторонники "микро-сервисной архитектуры"
которая в 1С опять же практически отсутствует (у нас всегда Монолит = Конфигурация + внешние отчеты/обработки).

так что вопрос остаётся открытым - что такое "слабо-связанные элементы" в 1С
(во-первых надо определить про какие "элементы" идёт речь?
- на разных уровнях кода или метаданных конфигурации 1С это разные "элементы" и общее определение тут вряд ли применимо.

Видел "сторонников" такого разделение и "эмуляции" микро-сервисной архитектуры - как уход от "монолитного" 1С в сторону web- http- сервисов ...где 1С остаётся просто базой данных для "отдачи" и/или получения данных извне...
а вся логика выносится куда-то наружу (на сайт например) - но это опять не про "хороший" или "плохой" код 1С получается
artbear; wonderboy; +2 Ответить
16. wonderboy 379 27.04.23 17:02 Сейчас в теме
(13) По поводу "элементов" - я бы выделял модули, если мы говорим про код. Там ведь есть "публичная" часть в виде экспортируемых процедур / функций. И есть инкапсулированная - в виде НЕ экспортируемых.

На уровне 1С тоже есть более-менее изолированные вещи.

Например в БСП подсистема склонения объектов. Там можно сказать всего одна функция наружу торчит. Остальное все внутри спрятано. Если надо - можно углубиться. Но не обязательно.

Но в целом 1С да, не позволяет хорошо свои "объекты" изолировать. Взять те же Присоединенные файлы. С ними уже надо какие-то связки в коде прописывать в формах, отдельные метаданные добавлять (пусть и по шаблону, но все это лежит в общей куче). Не особо красиво, но опять же - значительная часть логики скрыта в модуля, в которые и лазить не приходится.
20. TerveRus 31.07.23 15:14 Сейчас в теме
(9) цель отличная, а вот примеров очень не хватает. Непонятно, что за трюки и велосипеды. Непонятно как надо делать, а как делать не надо. Пока все очень абстрактно.
3. Serg O. 263 27.04.23 13:36 Сейчас в теме
насчет "непонятных" переменных... название может быть максимально понятным и длинным,
например, КоличествоСтрокТаблицыЗначенийИзРезультатаЗапросаПоПартиямТо­варовНаСкладах

но работать с таким "паровозом"... и "читать" код с таким длинным названием невозможно!
Иногда проще и удобнее - назвать её "математической" переменной N,
ну или для любителей "русских" переменных КолСтрок
6. wonderboy 379 27.04.23 13:53 Сейчас в теме
(3) Да, вы правы. Поиск компромисса как раз выглядит как на картинке из 1-го коммента :)
Если переменная будет актуальна только "в пределах одного экрана", то можно и не заморачиваться сильно с хорошим названием.
А вот если в процедуре на сотню строк, или это что-то экспортное, то приходится подумать.
Я, например, ничего против длинных наименований не имею. В пределах разумного конечно. В длинных наименованиях моно сокращения применять общепринятые. ТаблицаЗначений - ТЗ, Документ - Док и т.д.
4. Serg O. 263 27.04.23 13:41 Сейчас в теме
4. Трюкачество - вероятнее всего Вы имели ввиду уже есть "устоявшийся" термин - "индусский код"
7. wonderboy 379 27.04.23 13:55 Сейчас в теме
(4) Ну индусский код - это прям смесь всего-всего.
Смотрите, модельный трюк

A:=A+B; B:=A-B; A:=A-B;

что делает этот код?
Подсказка - экономит несколько байтов памяти! :)

Это я не то что из реальной жизни пример привожу. Чтобы мысль свою проиллюстрировать.
8. Serg O. 263 27.04.23 14:03 Сейчас в теме
(7) обмен значениями А и B...
в конце А = B а в переменно B = значение изначальной A
тут "трюк" действительно оправдан, без 3-ей переменной,

индусский код - когда простое решение - запутано максимально сложно...
в противоположность "оптимальному" коду или "минимализмам"

и к такому "индусскому коду" может (и обычно и приводит) разделение на "слабо-связанные элементы"
10. wonderboy 379 27.04.23 14:11 Сейчас в теме
(8) Про "слабо связанные элементы" - я вам на предыдущий комментарий пояснил что имею ввиду.
14. BigClock 27.04.23 15:44 Сейчас в теме
По собственному опыту основные проблемы, которые усложняют разбор кода, следующие.
1. Большое количество закомментированного кода. Бывает так, что в больших по объему процедурах/функциях идет частое чередование незакомментированного и закомментированного кода. Это сбивает с толку, приходится долго вчитываться, чтобы понять, что закомментированно, а что нет, и как вообще работает процедура/функция.
2. Высокая степень вложенности блоков кода. Это могут быть вложенные циклы, условный оператор, вложенные друг в друга. Чем больше глубина вложенности, тем сложнее понять, какой конкретно код исполняется и в каком порядке, а уж тем более что-то доработать.
3. "Километровые" запросы. Особенно, если они внутри условного оператора. Для улучшения понимания их лучше перенести в отдельные функции (ТекстЗапроса<...>), возвращающие текст запроса. Еще лучше, если и сам запрос возможно упростить/оптимизировать.
Рамзес; artbear; Serg O.; wonderboy; +4 Ответить
15. wonderboy 379 27.04.23 16:56 Сейчас в теме
(14) Отличное дополнение!

По поводу блоков закомментированного кода - это да, при том что для меня лично он НИ РАЗУ не был полезен. Ладно еще иногда типовой код комментят и свой ставят. Но бывает сначала один разработчик что-то написал. Потом его второй закомментировал свое написал, потом еще третий.

По высокой вложенности - я в таких случаях стараюсь выделять в отдельные процедуры какие-то части логики выносить. Чтобы в отдельной процедуре было не более 2-3 уровней вложенности условий/циклов.
17. Serg O. 263 28.04.23 11:20 Сейчас в теме
хороший инструмент проверки кода на "стандарты 1С" - Феникс ( Phoenix BSL )
который работает прямо из стандартного конфигуратора (по сочетанию клавиш Ctrl + Shift + I )
и относится к числу "статических анализаторов" см. подробнее Инфостарт - статья № 1656631

скачать и установить файл MSI (для Windows) можно с GitHub - Релизы
svezr; triviumfan; wonderboy; +3 Ответить
18. maksa2005 534 04.05.23 09:44 Сейчас в теме
2. Непонятные названия процедур, функций, переменных.

Не согласен. Я называю их так мне удобно, а так как нужно. Я пишу код чтобы в первую очередь понимать самому, а не то когда-то будет вместо меня.

3. Велосипедостроение.

А как без этого? Вы думаете что надо следовать только по прямой линии и никуда не сворачивать? пффф

читать код типовых конфигураций

Вот зачем мне это? Думаете что если там все так "шедевреально" написано, так значит компания 1С бога за 1 места пощупала? Не стоит равнять на них. Безупречных нет потому-что они все в могиле...
19. TerveRus 31.07.23 15:13 Сейчас в теме
(18) типичный неадекват, который всегда "знает лучше" и ему наплевать на коллег.
Надо было ФИО написать, чтобы Вас даже на собеседования не брали.
21. maksa2005 534 31.07.23 15:16 Сейчас в теме
(19)ахахахахаха Да пускай и не берут)
Оставьте свое сообщение