Мне посчастливилось работать в организации, которая прилагала добросовестные усилия для расширения полномочий своих команд. И я работал в других местах, где этого не было.
Поэтому, работая в качестве ведущего разработчика, я на собственном опыте убедился в разнице между этими двумя понятиями: поддержка и полномочия… что противоположно поддержке? Не совсем бесправие, скорее… бессилие или немощь.
«Бессилие», потому что в нем нет «силы». Постоянно нужно тянуть и подталкивать. Сам по себе он не сдвинется с места.
Что я имею в виду? Давайте поговорим о том, как бесправные в отношении разработчиков компании влияют на техническую работу.
О боже. Столько тем на выбор — неэффективное использование ресурсов; плохая документация; отсутствие значимых способов улучшить процесс снизу.
Но я — руководитель отдела разработки. Я подхожу к этому с инженерной точки зрения. Большинство книг и статей, посвященных процессу расширения прав и возможностей, не слишком глубоко рассматривают, как он непосредственно улучшает инженерный процесс.
Я здесь, чтобы исправить эту ситуацию. Но чтобы понять, как расширение прав и возможностей продвигает нас вперед, мы должны сначала понять, как недостаток прав и возможностей сдерживает нас.
Давайте посмотрим на гниение кода.
Технический долг: чужая проблема
Меня не устраивает концепция «технического долга«.
Когда я впервые услышал этот термин много лет назад, он показался мне очень умным. Это отличный способ передать идею о том, что за решения, которые обменивают долгосрочную стабильность на краткосрочную выгоду, приходится платить.
Но предотвращает ли эта концепция принятие таких краткосрочных решений? Насколько я знаю, нет.
Насколько я могу судить, наиболее распространенное понимание технического долга заключается в том, что это акт пренебрежения со стороны слишком торопливых или слишком неопытных разработчиков.
Я имею в виду, что такой тип повреждения кода действительно случается. Инженеры, которым не позволяют потратить время на «правильный код», будут создавать плохой, некачественный код. Неопытные инженеры, если их оставить без присмотра, могут пронестись по кодовой базе, как торнадо, оставляя за собой разрушения.
Однако общепринятое понимание технического долга возлагает бремя ответственности на плечи инженеров. Это и ограничение по времени, и желание уложиться в сроки, и найти какого-то другого козла отпущения. Если бы только инженеры были лучше, если бы только у нас были те 10x разработчики, о которых мы постоянно слышим, если бы только они работали больше, тогда мы могли бы избежать всей этой проблемы технического долга.
Поэтому ничто не мешает руководству сказать: ах, нам нужно, чтобы вы пришли в субботу, хорошо? Работа сделана. Дай пять!
Значит, нам нужно другое определение срок. Что-то достаточно сильное, чтобы шокировать тех, кто в костюмах.
Итак, кодовая гниль.
Настоящую кодовую гниль нельзя смахнуть под ковер — она является продуктом плохого процесса. Это прямой результат плохого управления. Только организационные изменения могут исправить ситуацию.
Вот как код начинает загнивать.
Гниль кода. Шаг 1: реальные решения не принимаются реальными игроками
Дорожная карта — это, по сути, финансовый артефакт. Она позволяет компаниям распределять бюджеты на краткосрочную и долгосрочную перспективу. Как таковые, они являются буквальным проявлением реальной власти в организации. Решения о том, что войдет в дорожную карту, носят ожесточенный политический характер.
Здесь многое зависит от «эго». Чем больше у вас прав на дорожную карту, тем больше денег вы контролируете, и тем дальше вы можете протянуть свои руки.
И вы сохраняете свое место в комнате, завершая проекты в срок и в рамках бюджета. Должны ли эти завершенные проекты хорошо работать? Теоретически, да. На практике своевременное завершение обычно является достаточно хорошим показателем успеха. Ущерб от остального можно контролировать.
Последнее, что может представить себе высшее руководство, — это отказ от контроля над дорожной картой. Такая идея для них просто немыслима. Любые проблемы в организации должны быть вызваны чем-то совершенно другим.
Гниль кода. Шаг 2: менеджмент
Ситуация неизбежно усложняется. Высшее руководство удваивает свои полномочия.
Самый распространенный способ добиться того, чтобы проекты на дорожной карте были завершены в срок и в рамках бюджета — это создать команду с особыми полномочиями — программный менеджмент. Эта группа является продолжением финансового подразделения компании. Таким образом, они подчиняются непосредственно высшему руководству.
Я никогда не встречал руководителя программы, который не был бы сфокусирован на сроках. Они будут допрашивать вас со всем рвением испанской инквизиции, не останавливаясь ни перед чем, чтобы добиться от вас обязательства назначить дату, какой бы гипотетической она ни была.
Затем они вводят эту дату в свои алгоритмы планирования. Я не знаю, что они видят в этих мистических зеркалах измененной реальности, но это некрасиво. Они почти всегда находятся в кризисе, и они устали от ваших оправданий.
И самое последнее, что они хотят услышать, это то, что вашей команде нужно отложить проект для устранения «технического долга».
Гниль кода. Шаг 3: план против реальности, разгромный удар
Проекты создаются для добавления различных функций в продукт. Учитывая финансовую природу дорожной карты, эти проекты обычно прямо или косвенно связаны с финансированием, что означает, что перед их началом необходимо рассчитать стоимость, а значит, общий объем работ должен быть «известен» заранее.
Большинство планов проектов, хотя и не все, достаточно умны, чтобы не вдаваться в детали реализации. Эти планы, вероятно, были выработаны различными менеджерами, архитекторами и даже людьми из команды проекта. Как только план составлен, а проект получил зеленый свет, инженеры должны следовать проектным рамкам и идти вперед.
Но проекты по разработке программного обеспечения — это как прыжок из самолета. Вы не можете понять, каково это, пока не сделаете это на самом деле.
Если бы продукт в целом был изображен на диаграмме, то область каждого проекта выглядела бы примерно так:
Обратите внимание, что ограниченность каждого проекта оставляет много серых зон, где никто не несет непосредственной ответственности за поддержание кода в рабочем состоянии. Даже если команда номинально занимается поддержкой конкретного домена, если она ориентирована на проект, у нее будет недостаток стимула работать над теми частями, которые не указаны в текущем плане проекта. Это не тот путь, который сделает руководителя программы счастливым.
Гниль кода. Шаг 4: серые зоны ведут к отсутствию ответственности
В процессе создания функций очень часто обнаруживаются пробелы в системах, находящихся вне вашей «ответственности». Сервисы, которые, по вашему мнению, должны быть там, там отсутствуют. API не обеспечивают то, что вам нужно. Общий код не справляется с вашим сценарием использования.
Что же делать команде, постоянно испытывающей нехватку времени?
Вы можете найти владельца и попросить его позаботиться об этом за вас. Однако в организации, управляемой проектами, службы или код, о которых идет речь, часто не имеют реального владельца. Команда, создавшая код, возможно, перешла к другим делам или расформирована. Даже если есть четкий владелец, команда обычно занята своими текущими проектами. Они вежливо поместят ваш запрос «в бэклог» — это еще один способ сказать: «Да, конечно, приятель».
В таком случае у вашей команды нет другой реальной альтернативы, кроме как работать в обход этих проблем. Вы можете создать новый сервис с нуля. Вы можете обернуть сервис в обертку, которая учитывает ваш сценарий использования. Вы можете добавить свою часть логики в общий код.
Если вы добросовестны (а я знаю, что вы добросовестны), вы отнесетесь к этому серьезно… или настолько серьезно, насколько это возможно. Вы напишете хороший код — который делает минимум для разблокирования вашей команды. Вы протестируете его — на соответствие вашему сценарию использования. Вы убедитесь, что не нарушаете то, что было раньше — расширяя базовые классы.
Но действительно ли вы думаете, что этот код будет так же хорош, как если бы он был создан командой, которая однозначно ответственна за долгосрочную заботу о своем продукте?
И вот в чем загвоздка. За годы и все эти итерации проекта даже код, созданный вашей собственной командой, становится внешним по отношению к вашим текущим проектам. Он становится частью серой зоны.
Гниль кода. Шаг 5: плохой код размножается
Любой опытный инженер-программист знает, что куски полуразрушенного кода — обычное явление. Часто это происходит потому, что, когда мы только пишем код, мы не совсем понимаем, как он будет использоваться. Любая стоящая команда пересмотрит старые решения и отрефакторит любой шатающийся код до более высокого стандарта, когда станут ясны модели использования.
Но когда никто не владеет доменом, в котором находится код, трудно понять как замысел, так и текущее использование. Этот случайный сервис. Этот безумная обертка. Это расширение кода. Кто его вызывает и зачем? Скорее всего, никакой документации нет.
Из-за этого рискованно и долго делать все то, что делают большинство хороших команд, чтобы их код был опрятным и удобным для работы. А у кого вообще есть на это время? Руководитель программы дышит вам в затылок, чтобы вы закончили следующую функцию.
Но разбитые окна приводят к разрушению домов. Тот сервис, который начинался как одноразовый, может стать свалкой для случайных функций. Если он понадобился для чего-то одной команде, есть шанс, что у других команд есть аналогичные (но не идентичные) потребности. Если нет собственника, то нет и настоящего дизайна. Если вам не повезет, вы получите худший сценарий: посмотрите на сервис со стороны и окажется, что он может обрушить всю вашу систему.
Обертка может быть переупакована так, что все забудут, что за ней скрывается. Затем приходит другая команда, которая меняет базовый код, и бам, половина ваших сервисов начинает выдавать странные ошибки.
Этот унаследованный класс, в свою очередь, может быть унаследован другими классами, связывая вместе несвязанные функции, требуя забавных труднопонимаемых состояний, вызывая странные условия гонки.
По мере роста системы «серые зоны» становятся все больше и больше по отношению к текущей работе над проектом, в конечном итоге доминируя над кодовой базой.
Возможности для провала из-за небрежности бесконечны. Как сказал Толстой:
Все хорошо построенные кодовые базы похожи друг на друга, но каждая связанная кодовая база связана по-своему.
Гниль кода. Конец: коллапс
Неухоженный сад зарастает сорняками.
Вы можете нанять лучших разработчиков, вы можете привлечь тренеров по Agile, вы можете даже попросить всех прийти на работу в субботу, но, тем не менее, кодовая база без реальных владельцев будет загнивать. Каждый раз.
А в масштабах компании гниение в конечном итоге приводит к краху. Каждый раз.
В этот момент ваше программное обеспечение либо перестает развиваться (все ресурсы уходят на поддержание шатающейся системы), либо вы начинаете все сначала со следующей версии.
Высшее руководство может расстроиться из-за некомпетентности своих инженеров, но что они могут сделать?
Посмотреть в зеркало? Наверное, нет.
Нет. Мы скажем им, что в этот раз все будет по-другому. Мы скажем им, что все усвоили урок.
И если вам дадут прекрасную отсрочку в работе над новой версией, обычно пройдет несколько лет, прежде чем гниение кода вернется.
Но к тому времени вы, вероятно, все равно уже уйдете, я прав?