Работа программиста похожа на работу художника. Всех нас ограничивает Кошелек Миллера: мы не можем оперировать сотнями объектов, поэтому рисуем картины мазками, а программы — небольшими кусочками. Еще Кошелек делает профессию творческой: создавая картину или программу, состоящую из огромного количества взаимодействующих частей, автор в процессе работы меняет свое представление о том, что должно получиться в конце. Когда абстрактные “идеи” начинают воплощаться в коде, оказывается, что воздушному замку нужны канализация, фундамент и аэродинамика. Программист не только пишет код, он постоянно меняет свое внутреннее понимание того, что создает.
Общение двух инженеров
Чтобы “понять” написанный кем-то код, программисту нужно воссоздать в своей голове ментальную модель, которая была к концу написания чужого кода. Ту самую, которая в процессе написания кода менялась. А вот языку программирования все равно. Ему ментальная модель не нужна. При этом одну и ту же идею можно сказать разными способами: можно тщательно сформулировать свою мысль, а можно “эту штуку в ту штуку”. В момент написания кода разработчик и язык программирования максимально близки, идею можно выразить как угодно. Но через месяц все эти идентификаторы “i, j, k” и функции по сто строк перестанут быть понятны даже их автору. Потому что ментальная модель живет в голове программиста пока он пишет код, пока держит в фокусе внимания контекст работы. Через месяц этого контекста не будет, и такой код станет протоколом общения двух инженеров, целиком состоящим из мата и междометий.
Если два программиста работают вместе над одной предметной областью, много общаются, пишут похожий код, используют известные обоим фреймворки и библиотеки — то понять код друг друга им будет не очень сложно. Так же как несложно понять друг друга автомеханикам, много лет работающим друг с другом и общающимся исключительно междометиями. Намного чаще я вижу другие ситуации: разработчики общаются мало, используют собственные “велосипеды”, в команде нет общего для всех стиля написания кода и фиксированного набора фреймворков с библиотеками. Если не прилагать усилия, то читать код друг друга им будет тяжело.
Что значит “прилагать усилия”? Оставлять в коде ментальную модель, которая есть в голове разработчика после написания этого кода или его модификации. В именах переменных, методов, классов, в комментариях к коду и к коммитам, в тикетах и базе знаний. Все это позволяет разработчикам лучше понимать код друг друга. Или нет?
Свой взгляд на мир
Даже если программист очень старается, чтобы его идеи были видны в коде, чаще всего они будут видны только ему. Причина — в молодости индустрии и отсутствии фундаментального образования. Множество программистов учились сами, их ментальные модели слишком сильно отличаются друг от друга.
Тикет “у тебя все сломалось”, написанный после устного общения с разработчиком, понятен и тестировщику и разработчику. Но только в первые десять минут после устного общения. Это аналог кода без оставленной ментальной модели. Тикет “Шестерня синей админки роняет последний транк” понятна тестировщику и разработчику, потому что использует общую ментальную модель, выработанную годами работы в компании. Такой тикет будет понятен им обоим и через полгода, но если его посмотрит новый тестировщик или разработчик — они не поймут ничего. Это аналог кода с ментальной моделью, которую не адаптировали для других людей. Только тикет, аккуратно и внятно описывающий что произошло, будет понятен кому-то кроме непосредственных участников событий.
Есть мнение, что неважно, какой код — главное, чтобы он решал поставленную задачу. В идеальном мире оно, наверное, так. В мире, где код пишется один раз и не содержит ошибок. А в нашем мире код эволюционирует годами, чинится, переписывается, меняется, становится основанием другого кода. Проявляет все качества, свойственные эволюции сложных систем. И нам очень важно, чтобы код можно было понять и поменять через полгода после создания. Совсем хорошо, если это сможет сделать кто-то, кроме автора кода.
Хороший код
Хороший код не просто содержит в явном виде «идеи», которые воплотил в коде разработчик. Эти ментальные модели нужно писать так, чтобы они были понятны максимально широкому кругу разработчиков. Из-за разных ментальных моделей разработчикам трудно понимать код друг друга. Особенно, если у них разная квалификация или специализация. Практика code review, про которую я уже рассказывал, позволяет быстро выявлять наиболее «непонятные» участки кода, постепенно обучая программистов выражать свои мысли понятным образом.
Писателей учат сначала языку, а затем на журналиста. Выражать свои мысли. А программистов “выражать свои мысли” не учат, не учат адаптировать свой код, чтобы его могли читать другие люди. Эту задачу приходится брать на себя тим лиду: сначала объяснять, зачем это нужно, затем показывать примеры, после чего организовывать code review и надеяться, что оно не скатится в агрессию разработчиков друг на друга.