Как написать красивый код
Автор курса по С++ в Яндекс.Практикуме Маша Гутовская рассказала, что такое красивый код, и объяснила, почему начинающим разработчикам важно сразу учиться писать код красиво. В конце текста вас ждет чеклист с советами и полезными материалами.
Зачем писать красивый код
Красивый код — это работающий, понятный и читаемый код, который написан по определённым стандартам. Такой код экономит время самого разработчика и его коллег, потому что он структурирован и понятно оформлен, его легко читать и использовать, а написанные на нём программы легче поддерживать, «дебажить» и тестировать.
Если красивый код станет привычкой, принципом работы, с которым вы входите в профессию, то вам будет гораздо проще в дальнейшем. Попав в компанию, которая работает по общепринятым стандартам, вам не придётся переучиваться и менять собственные подходы к разработке.
Это также может сослужить добрую службу на собеседовании. С большей вероятностью рекрутеры отдадут предпочтение тому разработчику, который умеет писать красивый код.
Три уровня красоты кода
Я занимаюсь проектами для интернета вещей, умного дома и медицинского оборудования. Обсуждать красоту кода я буду на примере С++, так как работаю на нём. Но думаю, что мой подход актуален для любого языка. Я бы выделила три уровня красоты кода.
Визуальный уровень
Вы работаете не в вакууме, у вас есть коллеги, начальники, подчинённые. Даже если код вы пишете один, его кто-то использует. Чтобы избежать вкусовщины и разночтений, в IT-компаниях создают так называемые coding conventions — стандарты оформления кода. Это фиксированный набор правил, который определяет, как должен выглядеть код в компании. Многие разработчики создают собственные руководства. Некоторые из них выложены в открытых источниках, к примеру, руководство по стилю Google лежит на GitHub. Если вы разделяете эти положения, используйте их для написания своего кода, а опытный наставник поможет вам исправить шероховатости.
Уровень восприятия
Код должен быть красиво организован. Важны названия переменных, размеры классов, функций и методов, а также частота использования условных выражений. Обилие if, else и switch case создаёт нагромождение условий и частных случаев. И это не только визуальная проблема: такой код сложнее понимать, дорабатывать и поддерживать.
Структурный уровень
Код должен быть продуман с точки зрения архитектуры. Бывает, что он написан по всем правилам, но если вы попытаетесь внести изменения, поправить класс или фичу, то всё рассыплется. Просто потому, что архитектура кода плохо продумана.Представьте, что новому разработчику в команде нужно найти баг в программе. Для этого он должен суметь быстро и без посторонней помощи понять, как устроен ваш код: все элементы должны стоять на привычных местах и не должно быть неявных зависимостей.Чтобы избежать плохой архитектуры, рекомендую освоить принципы SOLID и писать код в соответствии с этими принципами. SOLID (single responsibility, open-closed, Liskov substitution, interface segregation, dependency inversion) — это пять принципов объектно-ориентированного программирования. Это набор правил, которым нужно следовать при создании структуры классов. Я советую подробнее узнать об этих принципах и других важных аспектах красоты кода, прочитав книгу Роберта Мартина «Чистый код».
Code smells и рефакторинг
Отчасти из-за отсутствия чёткой регламентации в отрасли возник термин code smells. Так говорят, когда код вроде работает и даже соответствует всем правилам компании, но что-то в нём не так. В таком случае полезно провести рефакторинг — переработку кода, которая не затрагивает его работу, но облегчает понимание. Подробнее об этом понятии можно почитать в книге Мартина Фаулера «Рефакторинг. Улучшение существующего кода».
Допустим, вы написали код. Прошло полгода, вы успели поучаствовать в разных проектах и написать не одну сотню строк. Стоит ли возвращаться к нему и делать рефакторинг? Обязательно. Во-первых, это повысит качество самого кода, а вы научитесь замечать детали, которые надо исправлять и которых стоит избегать в будущем. Во-вторых, вероятно, вам будет нужно время от времени рефакторить и чужой код — сможете набить руку на своём же старом. В блоке полезных ссылок в конце статьи вы найдете ссылку на отличный ресурс о том, как делать правильный рефакторинг.
Разберём код, в котором можно найти много проблем:
// The function CalcElements counts how many elements is equal to arg
int CalcNumOfVariousElements(const vector<int>& v, int condition) {
int i = 0;
int count = 0;
vector<int>& tmp_v = const_cast <vector<int>&>(v);
while (i != 10) {
if (v[i] != condition) {
tmp_v[i] = condition;
count++;
//ProcceedElementsCheck(v[i]);
}
i++;
}
return count;
}
Этот код вполне соответствует правилам оформления. Но что мешает понять его легко и быстро?
Запутанные наименования, которые только усложняют понимание
— Название функции не соответствует тому, что она делает.
— Переменная типа int названа словом «condition», что выглядит сомнительно с точки зрения логики. Обычно условием можно называть какое-то выражение, проверку чего-то. Тип int — это число. Сказать, что число четыре является условием чего-то, странно.
— В названии функции заявлено, что она должна считать элементы. Вряд ли пользователь ожидает, что с элементами вектора что-то произойдет, тем более, что контейнер передаётся как константная ссылка. Но внутри функции константность убирается, и элементы контейнера меняются! Поэтому вызов такой функции может быть небезопасен.
— Непонятно, что скрывается за числом 10. Важно это обозначить, чтобы после возможных изменений в программе не появился баг. Ведь если никто не вспомнит о значении, никто не проверит код на ошибки.
Визуальный мусор
— Мёртвый код (закомментированный вызов ProcceedElementsCheck). Довольно сложно, на мой взгляд, понять, какой логики придерживался автор на этом участке. Причина — закомментированный код.
Проблемы с документированием
— Комментарий над функцией явно устарел и сбивает с толку.
Вероятно, опытный глаз может заметить ещё множество недочётов. Больше примеров плохого кода также можно посмотреть в книге «Чистый код».
Как написать красивый код
1. Следуйте правилам оформления кода (или coding conventions). Даже если вы фрилансите или учитесь, приобретите привычку всегда писать красиво.
2. Используйте специальные инструменты. Для корректировки кода под конкретный стайлгайд существует множество различных плагинов, скриптов и шаблонов для разных сред программирования. IDE (Integrated Development Environment) успешно автоматизирует этот процесс, а вы сможете и время сэкономить, и новый навык освоить.
Вот несколько полезных инструментов для автоматизации.
Plug-in Beautifier для вашей IDE — плагин, который сделает код единообразным, отформатирует, уберёт всё лишнее.
Clang-format — инструмент для автоматического форматирования кода без запуска IDE.
Google C++ Style Guide — руководство по стилю Google, которое можно взять за основу и использовать для создания собственного стайлгайда.
3. Сделайте код понятным. Код должен быть написан так, чтобы без ваших комментариев всё было ясно. Используйте простые названия переменных, классов и методов.
4. Освойте принципы SOLID. Нужно, чтобы ваш код не рассыпался при попытках коллег внести в него изменения.
5. Не забывайте про ревью. Код-ревью — это процесс, во время которого ваш код просматривают и комментируют члены команды. Хороший ревьюер укажет не только на баги в коде, но и на архитектурные недочёты и плохой стиль написания. Кроме этого, он объяснит, как можно было бы сделать работу быстрее и проще. Чтобы писать красивый и правильный код, внимательно относитесь к комментариям ревьюера, и тогда с каждой итерацией недочётов будет всё меньше.
6. Оставляйте время для рефакторинга. После рефакторинга ещё раз протестируйте код. Будет лучше, если ошибки заметите вы, а не ребята из вашей команды или пользователи.
7. Изучайте код новых проектов в open source. Это поможет вам быть в курсе новых практик и подходов. Следите за проектами, которые вам нравятся, смотрите, как и на чём они написаны, задавайте вопросы разработчикам.
8. Читайте книги и ресурсы по теме. Это просто, но работает. Я рекомендую «Чистый код» Роберта Мартина, «Рефакторинг. Улучшение существующего кода» Мартина Фаулера и отличный ресурс о рефакторинге Refactoring.guru.