Разработка
Важность владения кодом
Как и любые отношения, код нуждается в постоянной «любви». Если мы будем постоянно «лелеять» его, он будет продолжать процветать.
«Ты пишешь это — ты владеешь этим». Это философия отдела разработки программного обеспечения, в котором я когда-то работал. Это отличная философия, обеспечивающая ответственность за любой написанный код.
Но это легче сказать, чем сделать.
Владение кодом может и звучит просто, но код легко может быть оставлен без присмотра с течением времени. Последствия этого огромны. Код превратится в спагетти, его будет невозможно поддерживать и вскоре он станет устаревшим куском $#!+ и никто не сможет понять, как он работает.
Каждая часть кода кем-то написана, так что автор — владелец, не так ли?
Это очень упрощенный взгляд. Это относится только к сольному проекту или небольшой команде для небольшого проекта.
На самом деле, самые важные и успешные проекты, даже если они начинались с малого, проходят различные этапы, которые превращают гордый блестящий код в жалкий фрагмент загадочного кода, которого все боятся и презирают.
Чтобы узнать, как это происходит, ниже приведены семь этапов эволюции кода проекта, который становится уродливым.
1. Рождение
Разработчик начинает совершенно новый проект с продуманной архитектурой и чистой структурой. Это достаточно небольшой проект, в котором один разработчик понимает весь поток и интеграции.
По сути, один человек владеет кодом.
2. Рост
У нас появляется больше разработчиков, которые вносят свой вклад в код. Возможно, команда из 3–5 разработчиков. У нас есть экспертные оценки кода. У нас есть парное программирование. Все понимают все части кода. У нас есть главный ведущий разработчик, который решает, какой конвенции следовать. Чисто и последовательно.
Команда, по сути, владеет кодом.
3. Повторное использование
В идеале, когда в проект добавляется больше функций, мы не хотим все переписывать. Мы стараемся использовать повторно как можно больше. Мы используем такие подходы, как объектно-ориентированное наследование, рефакторинг общего кода в некоторые общие классы.
Каждый разработчик владеет своей частью функций, но всем принадлежит общий слой. Всем нравится использовать общий слой, но люди стараются избегать его модификации, так как это может потребовать изменения кода у всех остальных.
4. Федерация
Когда у нас только одна команда из 3–5 разработчиков, их уже недостаточно для работы над всеми необходимыми функциями. Компания принимает решение нанять временных подрядчиков или одолжить членов команды из других проектов для работы над этим растущим проектом для удовлетворения неотложных потребностей проекта.
Код по-прежнему технически принадлежит команде, но команда пишет не весь код. Члены команды заняты другими функциями и не могут полностью владеть объединенным кодом. Подрядчики или временные члены уходят, оставляя код частично в своей собственности.
5. Автоматизация
У одного умного разработчика появляется идея еще больше ускорить работу, не имея дополнительных разработчиков. Он видит некоторый общий код и общие шаблоны, которые могут быть сгенерированы автоматически. Чтобы упростить процесс автоматизации, разрабатывается сложный алгоритмический генератор кода, который генерирует boilerplate код.
Никто не владеет сгенерированным кодом, так как он «хорошо сгенерирован». Со временем разработчики используют его, но не знают, как он работает внутри, потому что в этом «нет необходимости». Умный разработчик владеет генератором кода… но ненадолго… (см. этап 6 ниже).
6. Переход
Умный разработчик умен, он нашел работу получше и перешел в другую компанию. Некоторые другие члены команды также ушли. Возможно, организация была реорганизована. Команда сократилась. Руководство решило нанять новых людей для заполнения некоторых вакансий. Произошло несколько итераций переходов, пока первоначальная команда не изменилась и не наполнилась новыми членами команды.
Есть много кода, «принадлежащего» команде, но никто в ней не имеет чувства собственности. Половина знает часть кода, но подавляющему большинству остается изучать только «необходимые» основы. Любые изменения кода — это просто «заплатки», поскольку они пытаются избежать изменения всего, что является «оригинальным», поскольку никто не знает, как это работает.
7. Миграция
Через некоторое время все ненавидят работать над исходной кодовой базой. Некоторые рекомендуют переписать все приложение. Кроме того, представлен новый стек технологий. Поэтому нам тоже нужно переходить на новый стек технологий.
Однако в бизнесе понимают, что полное переписывание — это большой риск, поскольку приложение уже активно используется в продакшене. Его нельзя полностью переписать, что потребует времени и не гарантирует, что оно будет работать так же, как и существующее приложение.
Следовательно, решение состоит в том, чтобы медленно оценить, как можно медленно перейти на более новую систему, сохраняя при этом «устаревший код» живым. Старый «собственный» код теперь становится «горячей картошкой», и все стараются не прикасаться к нему.
Как вы можете видеть, в конце разработчикам не нравится работать над исходным кодом, который был хорошо заточен на рост и масштабирование.
Из вышеизложенного может показаться, что проблема была вызвана «повторным использованием», «федерализацией», «автоматизацией» и «переходом», но они не являются основной причиной проблемы.
Все фундаментальные проблемы сводятся к одной общей проблеме: «угасание чувства владения кодом с течением времени».
Как поддерживать хорошее владение кодом?
Чтобы обеспечить надлежащее управление собственностью, как при одном разработчике, так и в команде, я рекомендую следующее соображений.
1. Скажите «нет» совместному владению
Ни одна часть кода не должна быть в «совместном владении» (shared ownership). Если мы хотим, чтобы какой-то общий код был общедоступным, у него также должен быть разработчик или команда, которая полностью им владеет.
Владелец должен поддерживать благополучие кода, это руководящий принцип участия в коде (“собственность” на код по-прежнему позволяет другим вносить свой вклад, как и в любом открытом исходном коде).
2. Четкие границы и автономия
Владение кодом должно быть четко разделено границей: пакет, модуль или репозиторий. Это позволяет избежать двусмысленности, а также упрощает создание системы, которая управляет владением. Это также гарантирует, что код всегда находится в разумных пределах для разработчика или команды.
Хотя в идеале мы хотим большей согласованности между участками кода (например, один и тот же язык), мы должны предоставить каждому владельцу кода автономию в определении его структуры. Эта гибкость позволяет владельцу кода чувствовать себя более способным к написанию кода и страстно владеть им, а также для упрощения в дальнейшем развитии по мере необходимости.
3. Поставка кода еще не все
Код должен меняться… постоянно. Он требует постоянного обслуживания и изменений. Код, оставленный без присмотра в течение некоторого времени (например, 1-2 года), имеет тенденцию устаревать. Всегда есть что время от времени изменить и улучшить (например, обновление библиотеки, рефакторинг и т.д.)
Чтобы удостовериться, что код всегда обновлён, нужно выделять время на его улучшение, пока разработчики работают над другими функциями. Возможно, на рефакторинг кода, на улучшение тестов и внедрение новых методов разработки.
4. Удаление кода полезно
Учитывая, что каждый кодом кто-то владеет и время от времени нуждается в выделении времени на его пересмотр, каждый разработчик может владеть кодом только определенного размера.
Чтобы убедиться, что код поддерживается, кроме добавления новых функций и нового кода, бизнес должен также рассмотреть возможность удаления фич, которые больше ни на что не влияют. Такое удаление поможет сократить код, который необходимо поддерживать. (Вот почему четкое разделение кода для функции необходимо — для более легкого удаления фич.)
Если нам нужно увеличить количество функций, не устарев при этом, нам, возможно, придется подумать о привлечении большего количества разработчиков. Обслуживание кода не бесплатное.
5. Автоматизация не бесплатна
Автоматизация — одно из самых интересных направлений разработки программного обеспечения на начальном этапе. Работа над ней может быть сложной, но она приносит много удовлетворения.
Фактическая более высокая стоимость приходит позже — ее обслуживание. Нам нужно убедиться, что кто-то не только владеет ею, но и полностью ее понимает. Это необходимо для того, чтобы можно было решить любые проблемы или сделать улучшения, которые потребуются в будущем. Такая работа обычно сложна для следующего владельца, который не знает контекста кода автоматизации.
Автоматизация, хотя и кажется, что ее можно сделать один раз и навсегда и волшебным образом повысить производительность, должна время от времени развиваться, чтобы ее можно было хорошо обслуживать. Стоимость последнего иногда превышает первоначальную стоимость. Следовательно, нужно взвесить все, прежде чем погружаться в это.
Посмотрите статью “Скрытая стоимость автоматизации программного обеспечения” для понимания.
Хороший код — это хорошо поддерживаемый код
В разработке программного обеспечения нас научили многим аспектам создания масштабируемого и поддерживаемого кода, таким как написание чистого кода, хорошо комментированного кода и т.д. Все это отличные методы разработки программного обеспечения, которые должен соблюдать каждый разработчик.
Однако реальность такова, что во многих организациях код по-прежнему становится “наследием” (legacy) и, следовательно, становится тяжелым бременем для разработчиков.
В большинстве случаев проблема заключается в том, что этот код больше никому не принадлежит. Как только это происходит, качество кода резко падает и в конечном итоге он становится неуправляемым.
Как и любые отношения, код нуждается в постоянной «любви». Если мы будем постоянно «лелеять» его, он будет продолжать процветать. Если нет, то он быстро состарится и вскоре вернется и будет преследовать нас.