[Перевод] О важности владения кодом
Последние пару лет на работе занимаюсь внедрением и поддержкой человекочитаемости кода. Стараюсь следить за его чистотой и ясностью. Беспокоюсь о том, что бы всем всё было понятно. Пытаюсь говорить с бизнесом на одном языке. Переживаю когда нахожу код с bus factor = 1. Верю, что у каждого есть свои сильные стороны, которые можно и нужно использовать. Люблю решать захватывающие задачи, а могу — даже не интересные.
Наткнулся на данную статью случайно, когда находился в очередном поиске ответа на вопрос «Как же так?!» в интернете. Автор данной статьи занимается мобильной разработкой, но тем не менее его наблюдения и выводы разительно перекликаются с моими.
Владеет кодом тот, кто его регулярно поддерживает.
Photo by https://unsplash.com/@tierramallorca
Однажды я работал в одной компании где девизом команды разработки была фраза «Ты владеешь тем, что пишешь». Это отлично мотивирует нести ответственность за любой написанный код. Но сказать проще чем сделать.
Вопрос владения кодом звучит просто и поэтому может с легкостью оставаться без внимания долгое время. Но последствия этого могут быть плачевными. Код превращается в спагетти, становится неподдерживаемым и вскоре никто не понимает как работает этот устаревший кусок г*вн@.
Любой код был кем-то написан, а значит он и есть его владелец, так?
Этот упрощенный взгляд применим только для личных проектов или маленьких команд с маленькими проектами.
В действительности самые важные и успешные проекты проходят различные этапы, которые превращают гордо сияющий код в жалкие таинственные обрывки, которых все боятся и ненавидят.
Чтобы узнать, как это происходит, ниже приведены семь этапов эволюции кода проекта, который в итоге становится безобразным.
1. Рождение
Разработчик начинает совершенно новый проект с продуманной архитектурой и чистым, структурированным кодом. Этот проект достаточно небольшой, поэтому один разработчик понимает весь процесс и общую структуру в целом.
По сути один человек владеет кодом.
Код понятен и им владеет главный разработчик
2. Рост
В проекте появляется больше разработчиков, которые вносят свой вклад в код. Возможно собирается команда из 3–5 человек. Есть экспертные оценки кода, парное программирование. Все понимают все части кода. Появляется ведущий разработчик, который вырабатывает соглашения по работе с кодом и следит за их соблюдением. Всё чисто и согласовано.
По сути команда владеет кодом.
Код понятен и им владеет команда
3. Переиспользование
Чем больше функций (features — Прим. пер.) внедряется в проект, тем больше появляется возможностей переиспользовать написанное ранее, вместо того чтобы писать заново. Используются такие подходы как объектно-ориентированное наследование, выделение общих частей кода в общие классы т. д.
Каждый разработчик владеет своей частью функций, но общий слой принадлежит всем. Он используется на ура, но люди стараются избегать его модификации, так как это может потребовать изменения кода у всех остальных.
Никто не владеет общим кодом. Со временем понимание общего кода теряется
4. Объединение
Количество необходимых функций (features — Прим. пер.) растёт и команда из 3–5 разработчиков уже не справляется. Для работы над растущим проектом и удовлетворения его неотложных нужд компания решает нанять временных подрядчиков или одолжить членов команды из других проектов.
Технически код по-прежнему принадлежит команде, но она уже пишет не весь код. Члены команды заняты своими функциями и не могут полностью овладеть получающимся совместным (federated — Прим. пер.) кодом. Позже, когда подрядчики или члены других команд уйдут, код проекта останется в состоянии неполного владения командой.
Объединяемый код создан, но не имеет владельца. Тем не менее, команда в конечном итоге будет владеть этим кодом, но не будет полностью его понимать.
5. Автоматизация
У одного умного разработчика появляется идея как ускорить работу без привлечения дополнительных людей. В коде видны некоторые шаблоны и общие паттерны, которые могут быть сгенерированы автоматически. Для упрощения процесса такой автоматизации разрабатывается сложный генератор шаблонного кода.
Никому нет необходимости владеть сгенерированным кодом, потому что этот код «сгенерирован хорошо». Через некоторое время разработчик использует его, но уже не знает как это работает внутри, потому что в этом «нет необходимости». Умный разработчик владеет кодом генератора…, но ненадолго (см пункт 6 ниже).
Автоматизация очаровательна в самом начале. Но у пользователя сгенерированного кода постепенно теряется понимание того, что происходит.
6. Переходный период
Умный разработчик умён: он нашёл работу получше и ушёл. Некоторые члены команды тоже ушли. Возможно, организация была реорганизована. Команда сократилась. Руководство решило нанять новых людей для закрытия открывшихся вакансий. Произошло несколько таких итераций и первоначальную команду полностью заменили новыми разработчиками.
Команда по-прежнему «владеет» всем кодом, но теперь ни у кого нет полноценного чувства собственности. Половина из них знает часть кода, но подавляющее большинство изучает только «необходимый» минимум. Любые изменения в коде — это лишь патчи, так как все стараются избегать изменений в основном коде, потому что никто не знает как это работает.
Переходный период оказывает наихудшее влияние на код, если нет надлежащей передачи знаний с достаточным количеством времени для понимания кода. Новые разработчики, которые не пишут основной код, чувствуют себя далекими от кода. Хуже всего то, что никто не может легко понять сложный кодогенератор.
7. Миграция
Через какое-то время все начинают ненавидеть работу с основной кодовой базой. Некоторые начинают рекомендовать переписать приложение полностью. Кроме того появляется новый стек технологий на который мы тоже собираемся переходить.
Однако бизнес понимает, что полное переписывание — это большой риск, поскольку приложение уже активно используется в продакшене. Его нельзя полностью переписать, так как это потребует времени и не гарантирует, что оно будет работать так же, как и существующее приложение.
Принимается решение постепенно оценить, как можно медленно перейти на более новую систему, сохраняя при этом «устаревший код». Старый «собственный» код теперь становится «горячей картошкой», к которому стараются не прикасаться.
Все предпочитают «покинуть корабль» и работать с новой кодовой базой. Старый код теперь «дом с привидениями», который все стараются избегать.
Как вы можете заметить, теперь разработчикам не нравится работать с оригинальным хорошо спроектированым для роста и масштабирования кодом.
Может показаться, что проблема была вызвана «переиспользованием», «объединением», «автоматизацией» и «переходным периодом», но на самом деле не это является основной причиной проблем.
Основанием для возникновения всех этих проблем послужило «угасание чувства владения кодом с течением времени».
Как угасает чувство владения кодом?
Как видим, все начиналось хорошо. Но с течением времени дела шли все хуже и хуже, и так по спирали. Ниже приведены несколько причин:
1. Постоянно расширяющиеся функции
Программное обеспечение, которое только добавляет и добавляет функции, но не удаляет их, является бомбой замедленного действия. Нам кажется, что разработчики, которые постоянно создают все новые и новые функции, при этом продолжают до конца своей жизни поддерживать старые, которые они написали раньше.
Старые функции вскоре становятся не актуальными, поскольку авторы могут очень долго не прикасаться к этому коду, так как заняты работой над новыми функциями. И несмотря на то, что автору нравится код и у него сохраняется чувством владения этим кодом, существует предел тому, сколько он может в действительности контролировать.
2. Владеет каждый = никто не владеет
Такое происходит с общим кодом. Если нет человека или команды, которая следит за таким кодом, то вскоре это станет одним из нижеперечисленного:
Город-призрак — никто не хочет вносить туда изменения, так как есть шанс случайно зацепить другие функции. Вскоре никто не представляет как оно работает внутри.
Дикий-дикий запад — код постепенно изменяется и становится не универсальным, где каждая команда добавляет свои собственные уникальные условия обработки и API. Вскоре это превращается в беспорядок.
3. Кодируй, но не владей
Некоторым организациям нравится иметь группу разработчиков, которые перемещаются между проектами для их поддержки. Идея состоит в том, чтобы совместно использовать ресурсы между несколькими проектами.
С точки зрения бизнеса это звучит логично, так как действительно позволяет сэкономить ресурс разработки, но проблема заключается в том, что не ясно кто в конечном итоге будет владеть кодом, который будет написан такой командой.
В отличие от железного продукта (hardware — Прим. пер.), программный живет вечно и его необходимо время от времени изменять, чтобы поддерживать его в актуальном состоянии. Но при таком «временном» владении кодом он довольно скоро перестанет быть актуальным (become stale — Прим. пер.).
4. Упрощение через усложнение
Для ускорения написания кода иногда разработчики создают:
Сложные кодогенераторы для шаблонного кода
Сложные базовые классы или функции, которые должны упростить использование такого кода
Это отличные инициативы, которые действительно могут повысить производительность. Но стоимость тут заложена не столько в создании, сколько в поддержке. Поскольку это сложно, то велика вероятность что стоимость поддержки также высока, а передача знаний непроста и это зачастую игнорируется.
Очень скоро никто не будет понимать как это работает и никто не захочет к этому прикасаться.
5. Мы здесь не навсегда
Почти наверняка первоначальные разработчики кода не останутся с проектом. Они или перейдут в другую компанию, или на другую позицию или уйдут в связи с реорганизацией.
Обычно, через несколько лет полностью сменится вся группа разработки. Без четкого плана по передаче знаний, скорее всего новая группа:
не будет хорошо знать код
не будет чувствовать привязанности к коду
будет иметь разные предпочтения относительно того каким код должен быть
Со всеми вышеперечисленными причинами скорее всего чувство владения кодом постепенно угаснет.
Как сохранить хорошее чувство владения кодом?
Для обеспечения надлежащего управления кодом как одному разработчику, так и команде ниже приведены несколько рекомендаций:
1. Скажи нет общему владению кодом
Никакой код не должен оставаться «в общем владении». Если мы хотим сделать часть распространенного кода общедоступным, то у него должен быть разработчик или команда, которые полностью им владеют.
Основным принципом участия для владельца должно являться благополучие кода (the code wellness — Прим. пер.). При этом такой код по-прежнему позволяет другим вносить свой вклад, как и любой другой открытый код.
2. Четкая граница и автономность
Владение кодом должно обладать четкими границами: пакет, модуль или репозиторий. Это позволяет избежать двусмысленности, а также упрощает создание системы по управления этим самым владением. Это также гарантирует, что размер поддерживаемого кода всегда находится в разумных пределах для разработчика или команды.
Хотя в идеале мы и хотим большей согласованности в используемом коде (особенно, если это один и тот же язык), тем не менее мы должны предоставить каждому владельцу кода автономию в выборе его организации. Такая гибкость позволяет владельцу кода чувствовать себя более вовлеченным и не терять мотивацию для дальнейшего развития кода по мере необходимости.
3. Выгруженный код не значит окончательный
Код должен меняться… постоянно. Он требует регулярной поддержки. Код, который остаётся без присмотра на некоторое время (1–2 года) имеет тенденцию становиться устаревшим и неактуальным. Всегда найдётся что изменить или улучшить (обновить библиотеки, провести рефакторинг т.д.).
Чтобы код всегда оставался актуальным необходимо выделять время на его улучшение в то время пока разработчики работают над другими функциями (features — Прим. пер.). Это может быть связано с проработкой тестов, рефакторингом или внедрением новых практик разработки.
4. Удаление кода полезно
Учитывая, что для каждого кода периодически требуется выделение времени для его поддержки, каждый разработчик может владеть кодом только определенного размера.
Чтобы код оставался легко поддерживаемым, кроме добавление новых функций, бизнес должен думать о функциях, которые перестали быть актуальными или больше не используются. Такое очищение поможет сократить код, который необходимо поддерживать. (**Кстати это еще одна причина почему четкое разделение кода реализуемой функции способствует более легкому её удалению).
5. Автоматизация не бесплатна
Автоматизация — одно из самых интересных направлений разработки на начальном этапе. Работа над ней может быть сложной, но она приносит большое удовлетворение.
Реальная цена автоматизации выясняется позже — при её поддержке. Мы должны быть убеждены, что кто-то не только владеет этим, но и полностью разбирается как это работает. Это необходимо для того, что бы можно было решать любые возникающие проблемы или внедрять улучшения в будущем. Такая работа обычно становится чем-то устрашающим для каждого следующего владельца, который не разобрался в контексте кода такой автоматизации.
Однажды сделанная автоматизация хотя и может волшебным образом повысить продуктивность, но время от времени требует развития, чтобы сохранять свою актуальность. И стоимость каждого следующего шага иногда превышает стоимость шага первоначального. Поэтому необходимо иметь это ввиду прежде чем делать каждый следующий шаг.
Владеет кодом тот, кто его регулярно поддерживает
В разработке есть множество практик для создания масштабируемого и поддерживаемого кода, такие как написание чистого кода, хорошо прокомментированного и т. д, которых должен придерживаться каждый разработчик.
Однако в реальности, во многих организациях код по-прежнему превращается в устаревший (legacy — Прим. пер.) и, как следствие, ложится тяжелым бременем на разработчиков при его поддержке.
В большинстве случаев проблема заключается в том, что у такого кода больше нет владельца. Как только это происходит, качество кода резко падает и в конце концов становится неуправляемым.
Код нуждается в постоянной «любви», как в любых отношениях. Если мы будем постоянно «лелеять» его, то он будет продолжать цвести. Если нет, то быстро состарится и вскоре вернется и будет нас преследовать.
А вот дополнительные взгляды на владение кодом в больших компаниях:
Для себя интересно будет узнать на сколько озвученное в статье перекликается с вашей реальностью разработчика.