Про читаемость кода 2.
Я уже писал про метаисследование о читаемости кода. Сейчас попалась ещё статья в тему. Дам тлдр и сверху от себя.
What Makes Code Hard To Read: Visual Patterns of Complexity
Автор концентрируется не на каких-то формальных метриках, а на визуальных паттернах, которые по его мнению не помогают делать код просточитаемым. Он не фокусируется на конкретных правилах стайлгайдов и делает выводы независимо вне зависимости от них. Более того, не фокусируется и на языках программирования.
В начале расматриваются 2 метрики, которые по некоторым причинам автору нравятся:
- Halsted Complexity
- "Cognitive Complexity"
Разбираются их корни, и автор делится мнением о хороших и сомнительных сторонах.
Далее три правила, которые автор считает наиболее важными для хорошей читаемости:
1. Хорошие имена очень важны, variable shadowing осуждаем.
2. Предпочитать более короткое время жизни для переменных.
3. Знакомые паттерны использования переменных лучше новых.
(где он не прав?)
И выделяет свои 8 паттернов для улучшения читаемости.
Статья очень разумная понятная адекватная. Надо почаще показывать коллегам.
Я очень не люблю лишние отступы. Ведь когда вы увеличиваете вложенность, приходится держать в голове всё больше причин нахождения в конкретной точке. Коротко и по делу это показано тут: https://minds.md/zakirullin/cognitive#nested-ifs
Когда код менее вложен, он более линеен. Вы живёте полной жизнью разработчика, который решает задачи, а не грузит голову.
Очень частый паттерн, который я ловлю на ревью это
if (something) {
...
...
...
...
...
...
}
return var;
хотя можно
if (!something) {
return var;
}
...
...
...
...
...
...
return var;
И эти отступы аффектят 5-50 строк кода. Невыносимо.
Ещё, насмотревшись кода некоторых продвинутых коллег, мне стал нравится подход написания кода вида:
void Do(...) {
if (cond) {
DoOther();
return;
}
DoFirst();
DoSecond();
for (auto x : container) {
DoWithX(x);
}
}
Т.е. ваш код это набор разных блоков с адекватными именами. Это, во-первых, позволяет не растить функции, а, во-вторых, помогает читающему сосредоточиться на важных блоках и идти вглубь только необходимых частей кода.
Некоторые энтузиасты предлагают использовать fibonacci tabbing для того, чтобы избегать большой вложенности. Вам буквально невозможно будет читать код, который ушёл за экран из-за того, что это 6й вложенный if. Даже расширения для VS Code делают.
Я участвовал в изменении стайлгайда на довольно широкий круг разработчиков. Там мы в том числе обсуждали какие-то объективные причины принимать то или иное решение, почему это лучше другого (отсюда и вырос прошлый пост). Процесс выглядел примерно так:
- собираем пожелания по изменению
- выделяем самые популярные
- местами проводим опросы при неоднозначностях
- фиксируем изменения, подгоняем clang format под требования
- анонсируем об изменениях и на выходных переформатируем огромное кол-во кода.
Вынес я для себя тут несколько моментов:
- в процессе обсуждения люди бывают довольно радикальными, хотя по факту большинству фиолетово, сколько там эта строка или на каком месте скобки. Если вы не делаете что-то из рук вон выходящее, никто может и не почувствовать. Каких бы мнений публика ни придерживалась.
- [obviously but] на масштабе учесть всё невозможно. Иногда нужно принять решение крепкой рукой (или несколькими, но их обязательно должно быть мало)
- иногда заставить clang format что-то сделать так, как вы хотите, бесконечно сложно.
В общем случае пишите как хотите. Только одинаково (чтобы паттерны повторялись, да). И не делайте вот это.
