Перейти к основному содержимому

Стиль кодирования

Введение

Главное и единственное правило — однообразие.

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

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

Личные предпочтения — это не про стиль кодирования. Забудьте об этом и никому не говорите.

Правила кодирования не должны убивать индивидуальность. Но разработчики должны развивать элегантность своей индивидуальности в коде, чтобы это не приводило к ужесточению правил.

Каждый проект не обязан иметь одинаковый стиль кодирования. Время идет, технологии меняются, появляются новые версии языков программирования. Иметь десять проектов с одинаковым стилем кодирования десятилетней давности наверное удобно, но код десятилетней давности, с учётом скорости развития технологий, — это не очень хорошо. Это застой, отсутствие развития.

Проекты могут и должны иметь индивидуальные стандарты написания кода.

Почему это важно?

  • Меньше вопросов о том, как писать код в проекте.

Когда программист открывает незнакомый код для изменения, первым делом он смотрит, как написан этот код.

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

  • Меньше конфликтов при слиянии.

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

  • Поиск и предсказание кода.

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

Возможность быстро найти нужный образец кода экономит много времени и сил.

Сохранение кодовой базы в однообразном стиле облегчает процесс реорганизации кода (рефакторинг). Проще сделать автоматический поиск и замену, чем руками и глазами перебирать весь. Это также уменьшает количество ошибок из-за невнимательности.

  • Дисциплина.

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

Без фанатизма

Идеального кода не бывает и никогда не будет. Нет смысла жестко ограничивать свободу. Нет смысла тратить много ресурсов на вылизывание кода.

Жесткий запрет на добавление в кодовую базу кода, который не соответствует требованиям, особенно с применением автоматизированных инструментов — это путь к потере людей. Это также может замедлить решение проблем и достижение целей. В худшем случае, это может убить проект.

Необходимо соблюдать баланс между свободой и качеством.

Как сделать кодовую базу однообразной?

Первый шаг — настроить .editorconfig. Остальное будет зависеть от используемых языков программирования и технологий.

В некоторых случаях, можно настроить автоматическое исправление ошибок и сделать код однообразным. Например, в JavaScript/TypeScript можно настроить ESLint. В проектах C# можно использовать dotnet format.

Стоит ли тратить время на поддержание единого стиля кодовой базы в домашних (pet) проектах?

Да. Тренировка никогда не бывает лишней.

Общие рекомендации

Следующие рекомендации основаны на опыте командной работы в коммерческой разработке и на опыте работы над проектами с открытым исходным кодом.

Пробелы или табуляция?

В мире .NET, JavaScript, TypeScript, PHP, Python, (S|Post)CSS предпочтение отдаётся пробелам, т.к. они более предсказуемы.

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

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

Переводы строк

Проблема символов переводов строк наиболее актуальная для кросс-платформенных команд, когда члены команды работают под Windows, Linux или macOS.

Большинство современных сред разработки и некоторые клиенты git, по умолчанию, умеют определять неразбериху в символах переводов строк, и пожалуй, это является одним из раздражителей.

Проще всего использовать unix-стиль — символ \n. Но как показывает практика, у пользователей Windows все равно могут возникать проблемы с переводами строки. Также проблема будет проявляться при использовании обычных текстовых редакторов, которые не умеют автоматически корректировать стиль кодирования по правилам .editorconfig. В таких случаях, можно попробовать решить проблему на уровне git — параметр core.autocrlf.

Я обычно отдают эту проблему на откуп .editorconfig, но я также постоянно стараюсь следить за пробельными символами и проблемы с переводами строк в моём коде возникают редко.

Никаких лишних отступов

Пробельные символы в конце строк, пустые строки состоящие только из пробельных символов — это мусор.

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

Чтобы в коде не было мусора, необходимо настроить IDE на удаление таких символов (trailing whitespace).

Также рекомендую включить отображение пробельных символов, чтобы было видно, что в коде все хорошо или, напротив, требует корректировки.

примечание

Однако следует учитывать, что в некоторых языках, пробелы в конце могут играть определенную роль. Например в markdown два пробела в конце строки означают, что следует добавить символ перевод строки после строки (обычно строки в markdown разделяются пустыми стоками).

Каждый файл должен заканчиваться символом перевода строки

Это довольно старый стандарт, корни которого уходят в системы Unix.

Добавление одной пустой строки в конце файла позволяет не трогать предпоследнюю строку при добавлении новых данных.

- Файл без перевода строки в конце.
+ Файл без перевода строки в конце.
+ Новые данные. Из-за добавления символа перевода строки поменялась предыдущая строка.
Файл с переводом строки в конце.
+ Новые данные. Символ новой строки уже был и предыдущая строка не затронута.
+
примечание

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

Сортировка

Хорошей практикой является сортирование импортов/включений/пакетов в файл.

Это позволяет избежать бесполезных конфликтов при слиянии веток.

Обычно сортировка выполняется по алфавиту.

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

Многие IDE позволяют автоматически выполнять сортировку.

Можно пойти дальше и сортировать сущности в файлах. Например, локальные и публичные члены, константы, поля, свойства, методы. Это тоже неплохо работает и уменьшает вероятность возникновения конфликтов, главное чтобы правила были понятны и не доставляли неудобств.

Никаких закомментированных блоков кода

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

Если когда автор такого блока забудет о нём, то с большой долей вероятности, этот мусор останется в проекте навсегда.

В идеале, в головную ветку (master / main) подобный код вообще не должен попадать.

Однообразные кавычки

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

Это поможет избежать конфликтов с кавычками.

Какие использовать кавычки — зависит от проекта, используемых технологий и команды. Например, в команде C#/Java предпочтительней использовать двойные кавычки в коде JavaScript, потому что в C#/Java одинарные кавычки используются только для отдельных символов (char), а для строк (string) используются двойные кавычки.