Каким должен быть качественный код? Роберт Мартин выразил это невероятно точно, когда сказал: «Единственная адекватная мера качества кода — это количество восклицаний «какого чёрта!» в минуту».

image

Позвольте мне пояснить эту идею.

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

  • Какого чёрта! (с отвращением) — когда в некоем фрагменте кода нет необходимости.
  • Какого чёрта! (с восхищением) — когда программист сделал что-то очень удачное.
  • Какого чёрта! (с раздражением) — когда я не могу понять тот ужас, который находится у меня перед глазами.

Итак, что формирует первое впечатление от кода? Это то, насколько он чист и красив. Подобный код является признаком высокого профессионализма того, кто его написал.

Путь к мастерству кодирования идёт через две важные вехи. Это — знания и труд. Знания дают шаблоны, принципы, практические приёмы, эвристические правила, которые нужны для профессионального роста. Но эти знания нужно закреплять. Тут в дело вступает механическая и зрительная память, знания должны прочно обосноваться у вас внутри через постоянную практику и упорный труд.

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

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

Имена


Кендрик Ламар как-то сказал: «Если я соберусь рассказать настоящую историю, я начну её с моего имени».

В мире программ мы встречаем имена буквально повсюду. Мы даём имена функциям, классам, аргументам, пакетам, да чему угодно. Имена придумывают для файлов с программным кодом, для папок, и для всего, что в них находится. Мы постоянно изобретаем имена, и поэтому имена часто становятся тем, что загрязняет код.

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

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

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

Одна функция — одна задача


Луис Салливан однажды сказал замечательную вещь: «Форма следует функции».

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

Есть всего два правила написания чистых функций:

  • Они должны быть маленькими.
  • Они должны решать лишь одну задачу и должны делать это хорошо.

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

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

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

Код и комментарии


Вот интересное наблюдение, которое сделала Винус Уильямс: «Все делают собственные комментарии. Так рождаются слухи».

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

Комментарии, в лучшем случае — это необходимое зло. Почему? Они не всегда — зло, но в большинстве случаев это так. Чем старше комментарии — тем сложнее становится поддерживать их в актуальном состоянии. Многие программисты запятнали свою репутацию тем, что их комментарии, в ходе развития проектов, перестали согласовываться с кодом.
Код меняется и развивается. Блоки кода перемещаются. А комментарии остаются неизменными. Это — уже проблема.

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

Важность форматирования


Роберт Мартин однажды очень точно подметил: «Форматирование кода направлено на передачу информации, а передача информации является первоочередной задачей профессионального разработчика».

Полагаю, нельзя недооценивать эту идею. Внимание к форматированию кода — это одна из важнейших характеристик по-настоящему хорошего программирования.

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

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

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

Сначала — try-catch-finally, потом — всё остальное


Жорж Кангилем сделал верное наблюдение, когда сказал: «Человеку свойственно ошибаться, упорствовать в ошибке — дело дьявола».

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

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

Один из способов качественной обработки ошибок заключается в правильном использовании блоков try-catch-finally. В них включают потенциально сбойные места, и с их помощью организуют перехват и обработку ошибок. Эти блоки можно представить себе как выделение изолированных областей видимости в коде. Когда код выполняется в блоке try, это указывает тому, кто читает код, на то, что выполнение в любой момент может прерваться, а затем продолжиться в блоке catch.

Поэтому рекомендуется выделять блоки try-catch-finally в самом начале работы над программой. Это, в частности, поможет вам определить, чего от кода может ждать тот, кто будет его читать, при этом неважно, выполнится ли код без ошибки, или во фрагменте, заключённом в блок try, произойдёт сбой.

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

Итоги


Как выразить, буквально в двух словах, всё то, о чём мы говорили? Ответ на это вопрос — термин «чувство кода». Это, в мире программирования, эквивалент здравого смысла.

Вот что говорит об этом Роберт Мартин: «Чтобы написать чистый код, необходимо сознательно применять множество приёмов, руководствуясь приобретённым усердным трудом чувством «чистоты». Ключевую роль здесь играет чувство кода. Одни с этим чувством рождаются. Другие работают, чтобы развить его. Это чувство не только позволяет отличить хороший код от плохого, но и демонстрирует стратегию применения наших навыков для преобразования плохого кода в чистый код». По мне — так это золотые слова.

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

Программист, пишущий чистый код — это художник. Он способен превратить пустой экран в элегантное произведение искусства, которое будут помнить долгие годы.

В завершение нашего разговора о чистом коде вспомним слова Гарольда Абельсона: «Программы должны писаться, в первую очередь, для того, чтобы их читали люди, и лишь во вторую — для выполнения машиной».

Уважаемые читатели! Какие приёмы вы используете для повышения качества собственного кода?

Комментарии (36)


  1. werklop
    26.01.2018 15:55

    Добавлю свои 5 коп.:
    Имена — иногда смотришь код и диву даешься, как может писать такое человек, который не один год этим занимается(гляньте на код программ С/С++ в частности). Все эти сокращения, неосмысленные значения имен, а еще к этому приучают с универа и множества книг. Особенно смешно слушать отговорки о том, что это ради производительности. Вы серьезно??? Про компилируемые ЯП и говорить нечего, не буду строить из себя КО, а про интерпретируемые — для этого имеются минификаторы и без них нельзя выпускать код в продакшн!
    Книга Мартина — это один из must read для каждого разработчика, вне зависимости от ЯП. Очень жаль, что правильные навыки не прививают с ранних лет.


    1. Neikist
      26.01.2018 20:43

      1. werklop
        27.01.2018 14:14
        +1

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


        1. vyatsek
          30.01.2018 19:13

          Еще не стоит забывать про документацию к методу.


          1. werklop
            30.01.2018 19:18

            О какой документации вы говорите? Если метод понятное и осмысленное значение, то он не нуждается в какой-либо документации/комментировании. Мартин этому аж целую 4ю главу посвятил


            1. vyatsek
              30.01.2018 20:17

              О какой документации вы говорите?
              О документации к коду, методы, типы, поля.
              C# (Xml documentation ) и Java (JavaDoc) поддерживают документирование «из коробки», на другие языки вроде как есть «примочки».
              Если метод понятное и осмысленное значение, то он не нуждается в какой-либо документации/комментировании.
              Очень сильное и очень спорное утверждение. Я не знаю что там писал Мартин, но хотелось бы посмотреть какой-нить его рабочий код, которму лет 10. В теории всегда все красиво.
              Обычно, по необходимости, документацию пишут к публичному(public)/защищенному(protected) контакту фреймворка, или в каких-то широко используемых библиотеках. В legacy коде в принципе всегда понятно что он делает, но непонятно по какой причине написали его именно так.
              Хотел бы я посмотреть на людей, которые получают фреймворк без документации, бгг…


      1. FlamyXD
        30.01.2018 13:16

        Ну, а это 1с, там это считается нормальным, так думают разработчики языка.


  1. AlekSandrDr
    26.01.2018 16:04

    Столько на эту тему тертоперетерто!
    „Совершенный код“ Стива Макконнелла — почти 900 страниц обсуждалова! чуть ли не каждый год переиздается уже изданий 10 точно есть.

    Все равно автору спасибо за статью!


  1. AlekSandrDr
    26.01.2018 16:12

    1. Боритесь со сложностью
    2. Анализируйте процесс разработки
    3. Пишите программы в первую очередь для людей и лишь во вторую — компьютеров
    4. Программируйте с использованием языка, а не на языке
    5. Концентрируйте внимание с помощью соглашений
    6. Программируйте в терминах проблемной области
    7. Итерируйте, итерируйте и итерируйте
    8. И да отделена будет религия от разработки ПО


    1. RomanArzumanyan
      26.01.2018 17:07

      9. Верхние слои пишите для людей, а нижние для компьютера.


    1. BalinTomsk
      26.01.2018 22:07

      У меня стиль написания сильно улучшился когда стал покрывать юнит тестами.


      1. VolCh
        27.01.2018 00:31

        Причём часто улучшения заметнее, если писать тесты до кода.


        1. AlekSandrDr
          27.01.2018 10:14

          Это к принципам разработки… XP habrahabr.ru/post/197760

          В экстремальном программировании роль тестирования интереснее: теперь вначале идет тест, а потом код.


          1. VolCh
            27.01.2018 14:19

            XP предполагает большее. Чисто написание юнит-тестов до кода — это TDD.


  1. tehSLy
    26.01.2018 18:34

    Реально, сколько уже по этому поводу сказано, но все никак не могут понять: "самый лучший и чистый код — код, который еще не написан".
    А вообще, все уже давно придумано, несколько непонятно, зачем это перефразировать каждый раз (DRY, KISS, YAGNI)
    Такие дела


  1. charypopper
    26.01.2018 22:30

    „Совершенный код“ Стива Макконнелла, который упоминали выше — могли бы уже вынести в обязательный перечень при приеме на работу, потому что видеть посты на хабре в которых так или иначе описанное им уже много лет назад… ну как то не весело уже...


    1. AlekSandrDr
      26.01.2018 23:19

      Повторение — мать учения


    1. VolCh
      27.01.2018 00:32

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


      1. Atorian
        27.01.2018 12:07
        +1

        Обратите внимание на кол-во комментариев к статье. Все ведь по делу написано, но никто из новичков не задает уточняющие вопросы. Они еще не понимают зачем это нужно. Зато с удовольствием посмакуют новый плагин к реакту. Так что формат статей нужно менять. Надо разжевывать зачем это нужно. Чтоб и школьнику стало понятно.


        1. VolCh
          27.01.2018 14:19

          А может просто ушли читать книгу :)


          1. Atorian
            27.01.2018 14:47

            Мне пришлось приложить не мало усилий, чтобы мои коллеги осознали, что надо учиться и начали хотя бы статьи читать. Мне повезло с техлидом. Обычно народ боится брать толстую книжку в руки ) А толковая литература обычно 300-1к страниц.
            Так что сомневаюсь что они вот так сразу, не дочитав статью, а скорее всего они ее не дочитали, рванули читать что-то :)


        1. werklop
          27.01.2018 14:24
          +1

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


          1. AlekSandrDr
            27.01.2018 14:32

            хз! Я вроде как в теме, но все равно себя новичком считаю. С тестами у меня все совсем плохо


            1. VolCh
              27.01.2018 15:13

              Вы же как-то тестируете свой код? Или закоммитили не запуская и там как-то Q&A проверяют?


          1. Atorian
            27.01.2018 15:07

            Поддерживаю! Это как чистописание. Прописи для программистов.
            Вот только у школ и вузов другая задача стоит.
            Школы учат азам, там нет задачи из каждого сделать программиста.
            А в вузах все всегда на одноразовых задачках. Преподаватели обычно горе-теоретики, так что скорее всего и код не читают. Главное чтоб работало. А это не способствует развитию хорошего стиля кода/архитектуры. Теоретически это можно автоматизировать сбором метрик, но кто там заморачиваться будет?

            Та же ситуация в веб студиях — там проект делается левой ногой на выброс, никто там долго поддерживать его не собирается.

            По этому там недостаточно боли от плохого кода. Тесты не пишутся. Призрак архитектуры унаследованный от фреймворка.

            Только в компании разрабатывающей свой продукт или там где ценится качество(принципиально), люди могут дойти до осознания что надо что-то менять.
            К сожалению, если это дойдет до одного, но он не сможет объяснить другим — все пропало.

            Под разжевывать — я предлагаю рассказать про все эти принципы на примере рефакторинга какого-либо типового проекта. Но чтоб там изначально была боль, которую народ не понимает. Рассказать как это влияет на эволюцию проекта, с примерами, как это лечится. Пошагово, вводя принципы и практики по одной. Чтоб новички увидели что-то знакомое, поняли что не так с этим и научились как делать хорошо.

            Желательно при этом сделать это на примере JS UI приложения. Ибо имхо это самый большой пласт начинающих разрабов.


            1. VolCh
              27.01.2018 15:15
              +1

              Но чтоб там изначально была боль, которую народ не понимает.

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


              1. Atorian
                27.01.2018 15:28

                Тех кто понимают, что в коде проблема — не надо уже учить, сами знают что делать. А те кого надо учить — не понимают, им надо показать и рассказать.
                Перевести из «не осознанной некомпетентности» в «осознанную»

                sergeykorol.ru/blog/competence


                1. VolCh
                  29.01.2018 12:44

                  Боль могут понимать, но что делать не знать. Какая-то компетентность в диагностике симптомов, но осознанная некомпетентность в лечении болезни.


            1. FadeToBlack
              29.01.2018 21:50

              чтобы боль приносила пользу, она должна быть у человека лично. чужая боль — не более, чем буквы в учебнике…


  1. lxsmkv
    27.01.2018 01:05

    Может нужно бороться не с проявлениями, а с причинами?

    8. Многие из вас знакомы с достоинствами программиста. Их всего три, и разумеется это: лень, нетерпеливость и гордыня.
    — Larry Wall
    Из "50 цитат о программировании всех времён"


  1. FadeToBlack
    29.01.2018 11:59

    И не забывайте! Совершенный код нужен только программистам, пользователям нужны работающие программы. Эти вещи связаны… как бы это вам сказать… опосредовано.


    1. VolCh
      29.01.2018 12:45

      Пользователям часто нужно ещё и чтобы их "хотелки" воплощались быстро и дешево. А вот тут уже связь не столь опосредованная.


      1. FadeToBlack
        29.01.2018 15:27

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


        1. lxsmkv
          29.01.2018 17:43

          Я часто думаю о том почему построение ПО не похоже на построение зданий. Наверное, отчасти проблема в том, что заказчики хотят дворец, а платят как гастарбейтерам за постройку, простите, сортира в огороде. И сроки соответствующие. Что ж потом удивляться если их дворец похож на тот самый клозет.


          1. FadeToBlack
            29.01.2018 21:44
            +1

            Здесь играет большую роль нелинейность. Если хороший каменщик может класть кирпичи в два, три раза быстрее (ровнее, крепче) в сравнении с обычным, то у программистов это может быть 10x, 100x, 1000000x (если вдруг есть готовое решение). Некоторые программисты тянут в одного то, что десятилетиями делают огромные команды (не миф, я реально такое видел). И здесь очень легко ошибиться в выборе. Ну а некоторые сами виноваты. Однажды мне предложили вакансию в одном стартапе. Задачи были сложные, но опыт у меня релевантный был. Я назвал величину ожидаемой заработной платы, на что получил ответ: да я за эти деньги найму пять индусов, они мне все сделают. Я пожелал удачи.


  1. MrDaedra
    29.01.2018 13:35

    Главное в написании чистого кода — желание разработчика писать чистый код. Знаю много людей, которые сами могут все эти принципы перечислить, но пишут ужасный код.