Когда вы в последний раз сталкивались с качественно документированным кодом?

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

Давно ли вы встречали такой код? Неделю назад? Месяц? Год?

Лично мне посчастливилось увидеть такой код пару лет назад. И с тех пор я видел немало кода с… довольно грязной документацией.

Но разве можно винить в этом разработчиков?

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

Логично, что подавляющее число программистов ставят во главу угла написание кода, а не качественной документации. Зачем тратить несколько часов своего времени на создание того, о чем никто не вспомнит еще полгода, а то и больше.

Конечно, они будут делать какие-то пометки и оставлять комментарии. Информация о том, как устроен и что делает код, будет разбросана по файлам README, докладам с конференций, каналам Slack, каким-то внутренним документам и так далее. Иными словами, информация, которую разработчики не сочтут нужным сообщить, окажется просто недоступна.

И в будущем это создаст массу проблем.

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

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

А если авторы кода и вовсе покинули этот корабль… Поздравляем! Теперь вам придется потратить добрую пару-тройку месяцев, чтобы разобраться в корпоративном легаси и его беспорядочной документации.

Я бы очень хотел сказать, что утрирую и такие случаи — скорее исключение, чем правило, но… нет. Это не так.

Откуда берется некачественная документация

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

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

А еще разработчики любят кодить. Им не нужны дополнительные административные задачи, которые только удлиняют их рабочий день. Даже программисты, не обремененные давлением бизнес-процессов, не хотят тратить время на такую «ерунду».

Примечание для тех, кто говорит «мой код настолько чист, что ему не нужна документация»

Хороший код должен говорить сам за себя. Безусловно, я согласен с этим тезисом! Но ни один код в мире не покажет всю картину целиком. Даже самый чистый.

Почему было принято именно такое архитектурное решение, почему что-то было реализовано, а что-то нет — ответы на эти вопросы не даст ни один код.

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

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

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

Для этого и существует документация.

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

Хорошая документация упрощает жизнь новичкам, позволяет поддерживать код в актуальном состоянии и без проблем делиться им с товарищами по команде.

Вот если бы написание документации не было таким отвратительным занятием!

Как быстро писать качественную документацию

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

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

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

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

Пока не существует IDE, которая позволяла бы делать примечания в коде, подобно комментариям в Word или программах для просмотра PDF. Однако инструменты, интегрирующиеся с VS Code и IntelliJ и позволяющие создавать такие аннотации, существуют. Например, Swimm, довольно свежая штука. (Нет, мне не «занесли» рекламодатели, хотя у меня была возможность пообщаться с техническим директором этой компании). В будущем планируется интеграция Swimm с другими IDE.

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

Файл README пишется быстро, но парадигма непрерывного документирования заставляет разработчиков поддерживать его в актуальном состоянии. Это можно делать путем упоминания строк или цитирования фрагментов кода прямо в документации. Затем, когда код изменится, вы поймете, что тот самый документ высокого уровня пора обновить.

А если вы не хотите постоянно сравнивать свой README с актуальным кодом, не волнуйтесь: такие инструменты, как Swimm, предупреждают пользователя об изменениях даже в том случае, если вы используете IDE не из списка поддерживаемых. Но ничто не помешает вам делать это вручную или реализовать свой способ автоматизации.

Явные ссылки на ваш код в документации также дают еще одно преимущество: вы можете создавать walkthrough кода.

При работе с кодом (даже самым чистым) начинающим разработчикам не всегда бывает понятно, как один фрагмент кода взаимодействует с другим и какова логика взаимодействия разных компонентов. Здесь вам поможет walkthrough. Это что-то наподобие туториала, только не для конечного пользователя, а для разработчика.

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

Итак, непрерывное документирование — это практика, предусматривающая создание и обновление всех видов документации прямо в процессе написания кода. Она касается низкоуровневых встроенных комментариев, высокоуровневых документов вроде README, пояснений и всего, что хоть как-то относится к проекту.

Обновление документации облегчается путем прямого цитирования или создания ссылок на фрагменты кода. Такие инструменты как Swimm могут упростить документирование, особенно если речь идет о большом проекте.

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

Статус-кво документации — в топку. Сейчас самое время изменить это.

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


  1. vkni
    11.11.2022 18:02
    +9

    Ребёнок изобретает literate programming Кнута?


    1. funca
      11.11.2022 19:01

      Дети заказали статью для продвижения своего стартапа, на котором уже подняли $33 мульта. А сюда зачем-то ее перевели.


  1. ruomserg
    11.11.2022 19:35
    +6

    Все это прекрасно, но дело в том, что только в прекрасном мире розовых пони и единорогов (и я здесь не имеют в виду статический анализатор кода с хабра...) — можно за один прием написать код, тесты и документацию. Обычно оно бывает не так — начали писать код, обнаружили что есть противоречние в требованиях, или чего-то не хватает в БД или что-то еще. Подумали — переделали. Начали писать тесты — обнаружили что ранее просмотрели edge-case, подумали — порешали — отрефакторили, и так далее! Если к этому добавить еще и поддержание документации в актуальном состоянии — стоимость разработки еще увеличится! А клиент согласен за это платить ?!

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

    Но писать документацию параллельно коду с текущим состоянием ресурсов — IMHO утопия…


    1. vkni
      11.11.2022 20:34
      +1

      Понимаете, без конкретизации проекта это всё — размахивание руками.

      А проекты могут разниться по частоте модификаций от верифицированной стандартной библиотеки языка С (окаменевшие остатки деятельности мамонта) до исследовательского скрипта в Jupyter, который меняется раз в час, да и компилироваться-то полностью не обязан — там могут быть какие-то куски написанные 15 минут назад с ошибками, но отложенные "на потом". Или по сложности — от зубодробительного оптимизированного под класс машин вычислительного кода до кристально понятных примеров из SICP.

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

      В общем, море параметров. Поэтому без хорошего системного подхода получается только чепуха.


  1. torbasow
    11.11.2022 21:52
    +1

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


    1. alexshipin
      12.11.2022 04:22

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

      Комментарий с описанием задачи не считается документацией, даже после "раздраконивания".

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


    1. qw1
      14.11.2022 01:10

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

      Или он пишет, но «в своём стиле», который вам вообще не нравится.

      И никакой гарантии, что написанное вами будет хорошо понятно для других.


  1. semennikov
    12.11.2022 00:01
    +4

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


    1. ruomserg
      12.11.2022 10:07
      +4

      +100!

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

      А вот когда мы пишем определенные биты в пределы счета таймера, или включаем/выключаем ногу GPIO — это совершенно понятно с точки зрения «что мы делаем», но совершенно неочевидно «а нафига?». Потому что это включает ту часть системы, которая не представима в коде. А постоянно держать в голове еще и все аппаратное окружение (и его даташиты и проч) — нафиг-нафиг… И тут комментарии, которые поясняют причину — абсолютно необходимы.

      В общем, правило простое — если разработчик средней руки может быть озадачен некоторым куском кода («зачем тут это ?», «почему именно тут ?», «можно ли его перенести ?», и т.д.) — в этом месте должен быть комментарий.


  1. Svetozarpnz
    13.11.2022 11:02
    +1

    Написание кода дешевле его отладки и поддержания. Поэтому документирование легко встраивается в процесс разработки. Проблема остаëтся в том, что сам факт документирования не удешевляет поддержание кода. Точно так же как и написание кода искусство документирования должно развиваться и ему нужно учиться.

    Соглашусь, что в разработке этому уделяют малую часть усилий. Получается геометрическая прогрессия проблем: бизнес не умеет объяснить потребность, аналитик пишет неоднозначную документацию и тз, qa и программист интерпретируют эти задания по-разному, тест-кейсы не совпадают с кодом. В последствии вопросы поднимаются до уровня бизнеса и не решаются, пока всё не пройдут к общему знаменателю. Получается документирование даст эффект для отладки только если оно будет единым для всех уровней.

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

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


    1. ruomserg
      13.11.2022 12:06

      Опять акцентирую внимание на том, что ситуация хуже чем просто "… бизнес не может объяснить потребность"! Если он может ее объяснить хоть как-то — это уже счастье! А то он может даже не знать, что у него есть потребность…

      Я какое-то время думал об этом — и вот вам аналогия с врачом. Представьте себе, что к вам (как ко врачу) приходит пациент и с порога заявляет: доктор, у меня болит то-то и то-то, анализы я сделал такие и вот такие, заключения специалистов там-то и там-то — выпишите мне в соответствие со стандартом лечения то-то и то-то, да дайте направление к физиотерапевту. Это — бизнес с ТЗ и с развитыми внутренними компетенциями — тут да, берите да дейлайте… Но так обычно не бывает. Гораздо чаще бывает по-другому:

      — Либо человек приходит и жалуется что у него голова кружится (и поди-пойми от чего: может гемоглобин низкий, может курит много, может давление шалит, и т.д.) — и нужно долго и упорно разбираться, где там корневая причина или их совокупность.

      — Либо человеку просто стало плохо на улице, и он вам вообще не может ничего объяснить — а просто на ногах перестал держаться: делайте что хотите!

      — Либо (и это самый худший случай!) — пациент приходит, и уверенно перечисляет вам подробно симптомы, укладывающиеся в диагноз. Проблема в том, что эти симптомы — плод фантазии самого пациента, а болеет он совсем не этим…

      Поэтому, когда вы имеете дело с бизнесом — вы обречены работать (особенно, поначалу!) с размытыми границами и непонятными ожиданиями. Нужна одна-две-три итерации, чтобы бизнес разобрался — что у него НА САМОМ ДЕЛЕ болит, и в каких рамках он может действовать чтобы это исправить. Я не верю, что все это можно сопровождать документацией в таких количествах, которые предложены в статье. Точнее — возможно все, но кто-то должен за это платить: лишними ставками писателей, снижением КПД программистов которые пишут документацию на 70% дублирующую код, и т.д. Я пока не вижу консенсуса в среде заказчиков, чтобы они хотели такую документацию и были бы согласны это оплатить. Наоборот, через каждого первого — все хотят удешевить процесс разработки.


  1. MaryRabinovich
    13.11.2022 21:54
    -1

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

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

    Это вот явно про архитектуру, а не про сам чистый код как таковой.

    Причём напрямую про архитектуру он тоже пишет, и заодно упирает на "почему", а не на "как":

    Почему было принято именно такое архитектурное решение, почему что-то было реализовано, а что-то нет — ответы на эти вопросы не даст ни один код.

    и

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

    Если оставить только про архитектуру, статья толковая. Я, например, никогда не думала в ридми добавить эти вот "почему". Упомянуть там другие варианты. Бывало, так получалось само собой. Но никакой рефлексии на этот счёт у меня раньше не было.

    Пожалуй, это разумная рекомендация: вдруг выбранное решение где-то упрётся в стену. И будет проще вспомнить (перечитать), что тоже раньше рассматривалось. Выбрали самый простой вариант, например, но он с какого-то шага не позволяет развить логику глубже. И заранее были рассмотрены ещё три, и записаны. Так проще при случае сменить направление.

    Но документировать код построчно, это безумно. И в целом такое вот ощущение, что это он по инерции. Если прямо детально документировать архитектуру, потом и построчно начинаешь тоже. Потом ещё - каждую букву.

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


  1. Urub
    14.11.2022 12:30
    +1

    я не увидел в статье ни примеров хорошей документации кода, ни описание инструментов автогенерации документации (html, pdf) из комментариев кода
    и какой смысл такие статьи переводить или читать ?