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

На своей должности руководителя разработки я стал непосредственным свидетелем разницы между командой, которой предоставили мощь и… какой антоним у мощи? Они были не слабыми, а, скорее, немощными.

Силу команды постоянно нужно подстёгивать и стимулировать, сама по себе она не развивается.

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

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

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

Давайте изучим это на примере деградации кода.

Технический долг: не моя проблема


Мне не нравится концепция «технического долга».

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

Но предотвращает ли эта концепция принятие подобных кратковременных решений? Такого я не встречал никогда.

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

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

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

Поэтому ничто не мешает руководству сказать: «Нам нужно, чтобы ты поторопился и пришёл поработать в субботу, ладно?» Отлично. Дело сделано!

Но нам нужен какой-то другой термин. Нечто такое, что могло бы пробрать менеджеров в пиджаках.

То есть деградация кода.

Настоящую деградацию кода невозможно «замести под ковёр»; она становится результатом плохо организованного процесса. Это непосредственный результат плохого руководства, и устранить его могут только организационные изменения.

Вот, как это работает:

Деградация кода, шаг 1: реальные решения принимаются реальными игроками


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

Этот процесс затрагивает эго многих сторон. Чем больше у вас веса во влиянии на роадмэп, тем больше денег вы контролируете и тем власти имеете.

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

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

Деградация кода, шаг 2: на сцене появляется программное руководство


Поэтому когда ситуация неизбежно усложняется, высшее руководство удваивает давление.

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

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

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

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

Деградация кода, шаг 3: план проекта против реальности


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

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

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

Если продукт в целом показать на схеме, то предметная область каждого проекта будет выглядеть примерно так:


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

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

Деградация кода, шаг 4: серые области приводят к отсутствию ответственности


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

Так что же должна делать команда, постоянно находящаяся в условиях нехватки времени?

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

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

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

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

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

Деградация кода, шаг 5: плохой код размножается


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

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

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

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

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

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

С ростом системы серые области становятся всё больше по сравнению с работой над текущим проектом и рано или поздно начинают доминировать в кодовой базе.

Потенциал сбоев из-за небрежности поистине безграничен. Как сказал Толстой, «все качественные кодовые базы похожи друг на друга, каждая связанная кодовая база связана по-своему».

Деградация кода, эндшпиль: коллапс


Сад, за которым не ухаживают, зарастает сорняками.

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

А в больших масштабах деградация приводит к коллапсу.

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

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

Посмотреть в зеркало? Вряд ли.

Нет. Мы скажем, что на этот раз всё будет иначе. Мы скажем, что все сделали выводы.

И если вам повезёт работать над новой версией, то до возвращения деградации кода у вас будет несколько лет.

Но вы ведь к тому времени наверняка уволитесь, так ведь?

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

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


  1. rukhi7
    15.08.2024 14:06
    +11

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


    1. ImagineTables
      15.08.2024 14:06
      +1

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

      Разбился дорогой спорткар с нуворишем за рулём. Расшифровка чёрного ящика показала, что последние слова водителя были: «Смарите, посоны, как могу!».


      1. 2medic
        15.08.2024 14:06
        +1

        50% всех несчастных случаев начинается со слов: «смотрите, как я умею…» Остальные 50% со слов «нет, смотри как надо…»


  1. vdshat
    15.08.2024 14:06
    +8

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

    Сейчас стараюсь четко определить владельца кода или сам станавлюсь им. Тогда можно говорить о каком-то порядке или возможности придерживаться плана и поставки в срок.


    1. lorc
      15.08.2024 14:06
      +2

      Именно поэтому в ядре Linux (как и в любом уважающем себя open source проекте) в корне лежит файл MAINTAINERS, где вказаны владельцы всех подсистем, драйверов и других частей ядра. Вообще всех. Если у кода нет владельца - он скорее всего будет убран из ядра. И именно владелец решает нужно ли принимать вот этот конкретный патч и в каком виде.


    1. DenSigma
      15.08.2024 14:06
      +3

      Да, в "Делай как в Гугл" об этом написано. Вся кодовая база делится на всех разработчиков. Каждый модуль принадлежит только одному. Владелец может переделывать и рефакторить как пожелает.

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

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


      1. rukhi7
        15.08.2024 14:06
        +2

        ... Владелец может переделывать и рефакторить как пожелает.

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

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

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


        1. alamat42
          15.08.2024 14:06

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


          1. rukhi7
            15.08.2024 14:06

            Если коммуникация нормально налажена, то какие-то измененения апи модуля будут обговариваться заранее с пользователями этого модуля.

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

            Это действительно

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

            Эта проблема существует не зависимо от наличия или отсутствия владельцев.


      1. xxxDef
        15.08.2024 14:06

        Может в гугле и есть у всякого кода владелец, который 24/7 его обслуживает, но в реальности у программиста всегда есть какие то новые задачи в каких то более других модулях или проектах. Сделать его ответсвенным за какой то код который написан 5 лет назад и ожидать что он его будет пожизненно суппортить - это чушь. За годы работы у него накопятся миллион таких модулей, и на новые задачи просто не останется времени. Да и никто не будет платить такому программисту который занят не разработкой новых фич, а чисто суппортом того что и так как то работает. А еще среднестатистический программист просто забьет на такой суппорт, оно ж и так работает, а работает - не трогай.

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


    1. ImagineTables
      15.08.2024 14:06

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

      По-моему, вы всё поняли с точностью до наоборот ))

      У кодовой базы всегда ЕСТЬ реальный (безо всяких оговорок) владелец. Это контора, которая наняла программистов. Проблема в том, что такое владение обезличено и неэффективно. Владельцы компании могут вообще не разбираться в коде, а нанятые кодеры рассуждают по формуле «Оно моё? Меня е..т?». Вот к этому и сводится проблема «кодовая база без реального владения со временем деградирует». То есть, не хватает не супервладельца кодовой базы, а владельцев отдельных частей, которые будут приглядывать за ними. Как говорил Ленин, «хозяйчиков».

      Чтобы её решить, можно сделать программистов квази-владельцами: ты не можешь продать свой код, но можешь писать его как посчитаешь нужным, неся за свои решения всю полноту ответственности (ограниченную трудовым договором). А далее всё зависит от качества нанятых людей. Если они не дураки, то будут тащить и внедрять у себя хорошие практики и инновации (а дураков делать квази-владельцами себе дороже).

      Но чтобы это квази-владение работало, к нему нужно относится всерьёз. Какое же это владение, если к тебе пришёл какой-то, извиняюсь за выражение, координатор, который, в отличие от тебя, не смотрит 12 часов в день на код твоего модуля, и не разбирается во всех нюансах, и начал тебя приводить к единой линии? Это уже не владение, а чайка-менеджмент: прилетел, поорал чаечкой, насрал и улетел в туман.


      1. mvv-rus
        15.08.2024 14:06

        Чтобы её решить, можно сделать программистов квази-владельцами: ты не можешь продать свой код, но можешь писать его как посчитаешь нужным, неся за свои решения всю полноту ответственности (ограниченную трудовым договором). А далее всё зависит от качества нанятых людей. Если они не дураки, то будут тащить и внедрять у себя хорошие практики и инновации (а дураков делать квази-владельцами себе дороже).

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

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

        Вот и здесь - ответственность за качество кода должна компенсироваться компенсацией. Как именно - это, однако, вопрос сложный, с матценностями-то проще. Но, по-любому, брать на себя ответсвенность за качество кода забесплатно - это IMHO признак дурачины.


  1. AAArmand
    15.08.2024 14:06

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

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


    1. mvv-rus
      15.08.2024 14:06

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

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

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

      PS Кстати, метод манипуляции, когда группу людей, никакими интерсами не связнную объявляют "командой" и хотят, чтобы они совместно действовали в интересах манипулатора - этот метод используется не только в трудовых отношениях, а много где - в социальной психологии имеет даже специальное название: "техника гранфаллуна". Происхождение термина (тем, кто с боконизмом не знаком и не знает, что гранфаллун - это каррас, обращающийся вокруг ложного вампитера) и описание метода можно найти, к примеру, в известной монографии Чалдини (в разных изданиях она называется "Психология влияния" или "Влияние").


      1. AAArmand
        15.08.2024 14:06

        Все так, но в реалиях сегодняшнего рынка такого все меньше. Знаю лично несколько прецедентов, когда команда разработки всем составом куда-то уходила или наоборот приходила в компанию и так из раза в раз. А там где компания понимает, что такое настоящая долгосрочная мотивация (в том числе и денежная) такие команды задерживаются надолго

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


        1. mvv-rus
          15.08.2024 14:06

          Невидимая рука рынка диктует условия, все больше компаний вкладываются в свои ИТ команды на долгосрок

          Повторяю: команды не существует. И вообще, есть примета: когда начальник говорит "Мы - команда", то это означет, что он хочет наеобмануть работников. А существуют отдельные работники, зарплата каждому из которых платится отдельно.

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