Pull to refresh

Размышления о красивом коде

Reading time 7 min
Views 17K

О красивом коде много принято говорить, рассуждать, спорить, и тем не менее, все равно толком не ясно — что же такое «красивый» код и каким он должен быть. Сложность определения «красоты кода» неудивительна, ведь понятия о «красоте» у каждого свои, не только в мире программ, но и вообще, в мире людей. Тем не менее, существуют определенные общие критерии красоты, с которыми соглашаются большинство людей. Их сложно сформулировать, но подсознательно любой человек понимает, что вот эта вещь — красива, а эта — не очень.
Не так давно, был опубликован очень интересный опрос, разделяющий мнения разработчиков о красивом коде, согласно их опыту. На мой взгляд, получилось крайне интересное исследование. Давайте попробуем порассуждать о нем немного шире.

Сейчас много доступной методологической информации, формируются разнообразные школы, течения и даже формальные техники написания «красивого кода». В связи с этим, трудно не заметить, как молодые программисты увлекаются следованием методике, спорят, о казалось бы, неважных вещах вроде «считать этот кусок кода, соответствующим „дзену“ той или иной идеологии или нет. А если считать, то насколько он идеологически чист?

С другой стороны, более зрелые (а значит, циничные и прагматичные) разработчики, знают, что увлечение идеологией, часто является ребячеством. И наконец, совсем матерые гуру могут свести все практики красивого кода к мантре „пиши код, б--ть!“. Им кажется, что этого достаточно. Они просто не осознают, что красивый код у них получается сам по себе, просто в силу большого опыта и набитых шишек. Но, все-таки, какой он — красивый код?

Отвечая на упомянутый опрос, я оценил свой опыт разработки в 8 лет и отвечал в соответствующей группе. Меня сильно удивило, что мои ответы практически полностью совпали с самыми популярными в моей „возрастной“ группе. Значит, мои „ровесники“ — это мои единомышленники! Это же круто!

Если бы меня спросили прямо в лоб о том, что такое „красивый код“, то наверное, я бы ответил, каким-то общим набором фраз, в стиле Капитана. Для меня „красота“ кода определяется, пожалуй, его изяществом, отсутствием лишней сложности, наличием единой идеи… как-то так. Если бы мы всегда могли писать такой код… В реальной жизни Идеально Красивый Код можно увидеть только сферическим, и в вакууме.
Как бы ни были мы педантичны и идеалистичны, но мы работаем в рамках сроков. Даже если это работа над открытым и некоммерческим проектом, даже если мы вкладываем в него весь свой опыт, знания и душу, все равно, желание выпустить, наконец, результат своего труда в свет — это дедлайн, который рано или поздно придет. А поскольку есть дедлайн (некий рубеж, после которого коду придется покинуть его автора), то есть и компромиссы, на которые приходится идти, чтобы завершить работу в срок. Как ни крути, но наша работа сложна. Изящные архитектуры и решения не всегда озаряют наши головы. Так рождаются костыли, заглушки, хардкод и прочие „маленькие хитрости“.
Разница между тем „как хотелось“ и „как получилось“ тем меньше, чем лучше человек, как специалист. Когда разница очень мала, то такой код, как правило, красив.
Итак, давайте вернемся к вопросам, которые были поставлены в упомянутом голосовании о красивом коде:

Красивый код нужно писать… по возможности.


Именно так, „по возможности“. Нам всем хочется писать прекрасные программы, очаровательные в своем изяществе. Покажите мне человека, который хочет создавать дерьмовые вещи. Не думаю, что есть люди, искренне этого желающие. Беда в том, что не всегда получается. Поджимают сроки, поджимает отсутствие музы, знаний. Опытный программист, выполняя „некрасивое“ решение продумает путь его удаления в будущем. Он точно знает, что является допустимым злом, а что — откровенной грязью.
Менее опытный программист тоже не хочет грязнить, но его критерии „допустимости зла“ часто намного ниже. Допустимо именовать все переменные одной буквой, выносить их все в глобальную область видимости, не делать отступов в коде. Работает же.
По возможности такой код лучше не писать. Если нет возможности (опыта), то писать все равно надо. Дорогу осилит идущий, задача должна быть решена.

Считаю, что красивый код должен…


Вот здесь уже интереснее. Каковы неотъемлемые критерии красоты в коде?
Взгляните на код, где отступы сделаны по принципу „куда встал курсор, там и пишу“, переменные именованы без смысла, логика размазана по коду, взаимодействие с пользователем перемешано с кодом базы данных. Вам достаточно будет лишь беглого взгляда, чтобы твердо сказать: „Код ужасен“. Это код дилетанта, сильно-сильно начинающего программиста. Полагаю, вы все такой писали, когда для вас каждый цикл был „мозговым испытанием“. Это проходит с опытом, но очевидно, что красоты в таком коде быть не может.

На мой взгляд, красивый код должен быть понятным, почти как текст на естественном языке. „Мнемонически понятным“, гласил один из вариантов ответа. Мне кажется это самый главный критерий. Требование к единому стилю оформления — это одно из средств обеспечения мнемонической понятности. Наличие единого стиля упрощает понимание. Красивый код должен быть выдержан в едином стиле. Не важно в каком, но в едином. Простейшее соглашение, например, именовать переменные-члены класса, начиная с подчеркивания, в разы увеличивает читаемость. Маленькое подчеркивание резко выделяет в коде „локальные“ данные метода и данные, от которых зависит весь класс. Другой пример, единый стиль именования getter/setter методов. Если все они начинаются с некоторого префикса, но мозг мгновенно понимает, что это за методы, зачем они. Не нужно отвлекаться от основного чтения и лезть в другое место кода, чтобы получить дополнительные разъяснения.

Второй очень важный критерий — стабильность кода. Как правило, ее обеспечивают тестами. Стабильный код красив даже не внешне. Он красив ровностью своего исполнения. Я испытываю неподдельное удовольствие, когда код, который я считаю надежным, вдруг правильно отрабатывает, если ему подали на вход новые данные, на которые он не был рассчитан. Я радуюсь за такой код и даже восхищаюсь им (собой, собой, конечно, к чему лукавить). Стабильный код красив, как красив хороший спортсмен или музыкант. Он могёт, чертяка!

И последний, важный критерий — простота расширения. Тут и говорить много не получится. Ходит куча старых баек, вроде той, что мол, если бы конструктора кораблей попросили сделать лодочку, а потом навесить мотор, вместить 1000 пассажиров, не считая команды, 300 шлюпок и зенитную пушку, то он бы заорал „я вам не программист!“. Постоянными в нашей работе являются только изменения. Умение предвидеть их — это талант. Когда вы созерцаете код, где точки расширения изящно включаются в основную задачу, то вы говорите, „красиво!“

На мой взгляд, это единственные обязательные критерии „красоты“ в коде. Ни комментарии, ни объем, ни даже производительность не делают код „красивым“. Красивый и тормозящий код все равно красив (хоть и не очень). Когда глядишь в код — красиво, а как запустил — плюешься, да. Пожалуй, это как с красивым, но глупым и пустым человеком.

Считаю, что красивый код может…


О, вот тут вообще весело. Хорошо говорить про идеальность, хорошо учить других… Но все мы грешны. Кто никогда не прописывал жестко значение, вместо того, чтобы сделать опцию — пусть первым бросит в меня камень. Поговорим о грехах „красивого кода“.

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

Кто-то из умных людей сказал: „Комментарии не должны говорить ЧТО делает код. Комментарии должны говорить ПОЧЕМУ он это делает“. Золотые слова, с которыми сложно спорить. На вопрос „что?“ прекрасно отвечает сам код. Когда я вижу в коде сложную или неясную конструкцию мне важно понять — зачем она здесь. Что будет, если я ее уберу или поменяю? Если рядом с такой конструкцией будет комментарий, то, скорее всего, он будет в стиле „Присваиваем переменной А значение Б“. „Спасибо за помощь, черт побери!“, — ругаешься ты и начинаешь анализ.

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

Скорее всего, это присваивание „А=Б“ действительно важно, какой-то ключевой момент алгоритма, который автор счел нужным пометить. Он не написал „почему“ надо делать это присваивание, поскольку в тот момент он считал это очевидным. К этому комментарию нужно просто дописать „чтобы результат метода….“ и комментарий станет гораздо понятнее. Беда в том, что в момент глубокого погружения, автор не мог вылезти из уровня максимально детализации, не разрушив хрустальный замок. Комментарий предельно понятен, но бесполезен, если читающий не находится в состоянии погружения в алгоритм.

Когда код написан, то иногда его „причесывают“, и тогда комментарии переписываются и уточняются. И вот тут еще одна засада — комментарий рано или поздно устареет, код перепишут, а про него забудут.

Таким образом, требование „убирать комментарии, писать самодокументирующийся код“ весьма справедливо. Но каким бы хорошим ни был самодокументирующийся код, он прекрасно описывает „Что“, но редко может ответить на вопрос „Почему“. Красивый код может не содержать комментарии, но если они есть и объясняют почему написан тот или иной фрагмент, то они делают код еще красивее.

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

Краткое резюме

Каждый из нас безо всяких статей понимает — что такое красивый код. У красоты нет формальных критериев, но она ощущается совершенно четко. Красивый код, это тот, который не вызывает желания немедленно выделить все и нажать Delete. Удивительное единодушие всех „поколений“, принимавших участие в опросе о красивом коде, это подтверждает.

P.S.

Это моя первая статья для хабра. Я знаю, какие вы тут все строгие да суровые, поэтому очень прошу, если что-то кажется вам вопиющей фигней, то не поленитесь, пожалуйста, кроме минусов еще и написать пару слов — что именно не так, ладно?
Спасибо за внимание.
Tags:
Hubs:
+7
Comments 6
Comments Comments 6

Articles