Понятно, что очевидный (и правильный) ответ — «Потому что код нужно не только писать, но и читать».
Вряд ли этот ответ стоит целого поста, но автор им не ограничивается.
В последнее время мои коллеги раздражались на мои постоянные комментарии по поводу стиля в обзорах их кода.
Я уделяю все больше и больше внимания тому, что можно с полным основанием назвать косметикой.
Да, есть плохие стили кода, а есть и лучшие, но все это всего лишь условности.
Нельзя отрицать, что некоторые из них действительно улучшают общее качество кода, но сколько бы мы ни спорили о пробелах и табуляциях, они остаются субъективными предпочтениями, часто делом вкуса.
Однако меня беспокоит не качество кода, не столько напряжение глаз и случайные ошибки чтения, которые также определяют качество кода.
Мы часто боремся с ошибками, которых можно было бы избежать, если бы не спешка и недоразумения.
Разработчики не просто пишут код; мы тратим большую часть времени на добавление, удаление и редактирование небольших фрагментов кода, по сути, внося небольшие изменения в огромный код. Самостоятельные куски кода, написанные с нуля, встречаются редко — если, конечно, мы не начинаем новый проект. Большинство наших проектов — это наследие многих поколений разработчиков до нас.
Что бы мы ни делали — добавляли новый функционал или меняли старый — нам приходится читать код, чтобы понять, какая команда что делает и как лучше всего реализовать нашу идею.
Даже при работе над полностью независимым модулем или классом, написав первые строки, нам приходится возвращаться к ним снова и снова, чтобы вплести в них новый код. Как ни странно, чем опытнее я становлюсь, тем больше времени трачу на чтение кода перед его изменением, и мне это кажется логичным.
Написать новый код гораздо проще, чем понять и использовать существующий код, но самый простой путь не всегда является лучшим.
Наверняка, написать эту функцию сравнения строк, нечувствительную к регистру, в тридцатый раз, когда она нам снова понадобится, будет быстрее — или только мы так думаем? На самом деле, существует вероятность того, что в новую функцию закрадется одна-две ошибки, и мы не заметим ее, пока не станет слишком поздно.
Не намного сложнее приложить усилия и найти существующую реализацию, которую мы сможем использовать — возможно, даже в нашем старом коде, но для этого нам нужно уметь его читать.
(Я не думаю, что изобретать велосипеды — это серьезный грех; бывают случаи, когда это лучший выбор, но это уже другая история.
) Еще один замечательный побочный эффект чтения кода — обнаружение ошибок и сообщение об них, если не исправление их немедленно.
Разумный выбор между написанием нового кода или использованием существующего или библиотечного кода может быть сделан только тогда, когда учтены накладные расходы обоих вариантов — поиск потенциальных ошибок в первом случае или обучение и внедрение во втором.
К сожалению, это осознание приходит только с опытом( Эффект Даннинга-Крюгера ).
Вопрос о поддержке унаследованного кода или написании собственного — это совсем другая дискуссия; Замечу, что улучшать устаревший код почти всегда лучше, чем его уничтожать: это менее рискованно, всегда остаются рабочие фрагменты и есть код, который можно взять за основу.
Идея этой статьи заключается в том, чтобы избежать переписывания кода, разработчик должен уметь читать существующий код и читать его хорошо.
А для этого нужно уметь писать свой код так, чтобы он был читабельным.
Перейдем к конкретике.
Я считаю, что это важно для улучшения читаемости кода.
1. Последовательность.
Я без проблем могу читать код практически в любом стиле; Мне пришлось научиться приспосабливаться.
Если я думаю, что мне нужно читать код, я должен признать, что стиль может отличаться от моего любимого.
Есть только одна вещь, к которой невозможно адаптироваться: код, который выглядит так, будто его написал пятилетний ребенок, только что перешедший с QWERTY на QWERTY. Дворжак .
Независимо от того, выбираете ли вы стиль самостоятельно или он вам навязан, придерживайтесь его на протяжении всего проекта.
2. Последовательность.
Это настолько важно, что заслуживает двух верхних мест в списке.
Люди экспериментируют со скобками на следующей строке и скобками на этой строке, затем забывают об этом, и их эксперименты попадают в репозиторий, раздражая остальную команду.
Серьезно, экспериментировать со стилем — это хорошо, но не стоит этого делать.
3. Добавьте пространство.
Код похож на текст: все ненавидят читать «листы» текста без форматирования и разбиения на абзацы — так что это касается и кода.
Разделяйте блоки и области видимости пустыми строками; закрывающая скобка — отличное место для них.
Хотите добавить комментарий? Отлично, но вам не нужен газетный стиль, когда код отформатирован в две колонки — код слева, комментарии справа.
Это может быть полезно, но редко; обычно место для комментариев находится перед блоком или командой, а не рядом с ними; Перед комментарием лучше также добавить пустую строку.
Помните, что дискового пространства достаточно: разбивайте длинные функции, огромные классы и длинные файлы.
Сохраняйте разумный размер своих функций.
Используйте такие показатели, как цикломатическая сложность чтобы определить, когда ваш код становится слишком сложным и, следовательно, трудным для чтения и понимания.
Рефакторинг.
4. Оставляйте комментарии к баннерам!
Желание добавить пятистрочный баннер-комментарий внутри функции — хороший признак того, что вам нужно запустить новую функцию, которой будет предшествовать этот баннер.Я бы предпочел обойтись вообще без этого, но это лучше, чем одна функция на тысячу строк с полдюжиной баннеров.
Фактически, если вы хотите отметить начало нового логического блока, лучше сделать его функцией.
То же самое касается любых длинных функций, классов и файлов.
5. Не используйте магические числа.
Константы — отличный инструмент для именования чисел, на которых основан код. Значения по умолчанию, размеры контейнеров, таймауты и сообщения пользователя — это лишь несколько примеров того, что можно поместить в константы.
Только не заменяйте никакие числа константой — они не для этого придуманы.
6. Выбирайте заголовки с умом.
Существует много литературы об именовании переменных и функций и об опасностях выбора похожих имен.
Однако некоторые неосведомленные элементы по-прежнему настаивают на путанице в именах и повторном использовании переменных за пределами логических границ.
Имена должны быть не только осмысленными и однозначными, но и единообразными для всех функций, классов и модулей, а в идеале — во всем проекте.
Ну хотя бы попробуйте!
7. Не пишите цепочкой.
Многие люди практикуют объявление всех переменных одного типа в одной строке, разделяя их запятыми.
Это происходит из языков, которые требовали этого и не позволяли объявлять переменные после команд. Если язык это позволяет, объявляйте переменные как можно ближе к тому месту, где они используются, и не используйте их повторно (если только не для той же цели).
Аналогичный шаблон цепного кода возникает, когда результаты вызовов других функций передаются в качестве аргументов одной функции без сохранения их в промежуточных переменных.
Некоторые думают, что это делает его более компактным и нагромождают 3-4 вложенные функции.
Зачастую получается с точностью до наоборот, особенно если вам нужно проверить все побочные эффекты функций в поисках бага.
8. Ограничьте размеры строк и файлов.
Горизонтальная прокрутка ужасна: нельзя ожидать, что человек прочитает текст, прокручивая каждую строку влево и вправо.
У разных людей разные размеры экранов, и многие используют более крупные шрифты из-за плохого зрения.
При этом многие разработчики используют максимальную ширину своего экрана, а иногда и вовсе не ограничивают длину строки.
Это очень неудобно, потому что.
Во многих средах разработки плохая построчная расстановка переносов разрушает форматирование кода.
Хорошей отправной точкой является исторический стандарт в 80 символов в строке: он не слишком узкий и поддерживается большинством мониторов и настроек.
Если вся команда может обрабатывать строки длиной 100 или 120 символов, мы можем принять их в качестве стандарта; но здесь важно не переусердствовать, так как слишком длинные строки сложно прочитать самостоятельно.
Подумайте о газетах и журналах: насколько узки их колонки и как они читаются.
Строки, требующие при чтении двигать не только глазами, но и головой, создают дополнительное физическое напряжение и замедляют работу.
9. Сделайте границы явными.
Во многих языках области видимости неявны.
Первая команда после условного перехода или цикла в таких языках, как C, явно входит в его область применения, а следующие команды — нет. Если форматирование прошло неудачно, довольно сложно проследить конец блока, чтобы узнать, какие команды ему еще принадлежат, а какие уже не принадлежат. Форматирование, явно разделяющее блоки, добавление круглых скобок и пустой строки после закрывающей скобки, даже если тело цикла представляет собой всего лишь одну команду, значительно улучшает читаемость кода.
10. Комментарий.
Код, каким бы запутанным или непонятным он ни был, прекрасно понятен компьютерам.
Людям, с другой стороны, необходимо понимать не только то, что делает код, но также цель кода и причины, по которым он был написан таким образом.
Без понимания определенных конструкций, операций и значений ни один разработчик не сможет полноценно поддерживать код. Комментарии — отличный инструмент для передачи неочевидных нюансов кода.
Объясните бизнес-требования, предположения, требования, исправления и обходные пути.
Поговорите с другим разработчиком через комментарии.
Однако не бывает правил без исключений – не злоупотребляйте комментариями.
Не пишите «теперь произойдет ошибка» перед выдачей исключения — команда throw говорит сама за себя; лучше объясните, почему в этом случае ничего исправить нельзя.
В заключение отмечу, что некоторый код нужно сделать нечитабельным.
Да-да, твои глаза тебя не обманывают. Код, созданный на основе хаков, плохих практик или обходных путей, должен быть трудным для чтения.
Мой лучший пример — приведение типов.
Часто экземпляры объектов необходимо привести к определенным типам — это стандартная практика, но не совсем рекомендуемая.
Написание преобразования в несколько менее читабельной форме — хороший способ заставить читателя остановиться и убедиться, что это не ошибка.
Это чем-то похоже на курсив, который труднее читать и поэтому он выделяется.
Аналогично, обходные пути и хаки должны выделяться.
Маркеры TODO и FIXME — хорошее начало; на самом деле, если где-то в коде и должен быть баннер-комментарий, то он здесь — пусть известные проблемы вылезают из кода.
(Главное — не забыть их поправить! — прим.
) Как и большинство подобных статей, эта в первую очередь посвящена принципам читаемости кода, а не конкретным требованиям.
Они не жестко запрограммированы и ни в коем случае не являются полными.
Все языки, экосистемы, фреймворки и библиотеки имеют свои нюансы; вещи, явные в одних языках, могут быть двусмысленными и нежелательными в других.
Важный вывод — писать код для читателя, избегать путаницы в стилях, обращать внимание на контекст и решать, когда комментировать, а когда проводить рефакторинг.
Теги: #читаемость #хороший код #стиль программирования #Идеальный код
-
Двухфакторная Аутентификация: Защита Сети
19 Oct, 24 -
Как Мы Регистрировали Компанию В Ес
19 Oct, 24 -
Машинное Зрение И Медицина
19 Oct, 24 -
Почему Одни Люди Продвигают (А Другие Нет)
19 Oct, 24