СофтХабрахабр

[Перевод] Приходится выбирать, какой софт вам нужен: написанный вовремя или качественный

Хорошо. Надеюсь, что смог привлечь ваше внимание таким провокационным (и, признаться, утрированным) заголовком. Теперь позвольте его переформулировать в чуть более изящном и менее завлекающем виде:

В принципе, софт можно написать либо вовремя, либо хорошо, но не то и другое одновременно*

* за исключением считанных случаев в сложившихся высокопроизводительных командах

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

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

Да, формально «дедлайны» там были, но далеко не железобетонные. Переведено в Alconost
Мне доводилось работать и на проектах без жестких дедлайнов. Именно на этих проектах у нас получался самый лучший софт, были самые довольные разработчики и, в целом, эти проекты оказывались в числе наиболее успешных среди всех, над которыми мне приходилось работать. Все понимали, что сроки у нас гибкие, и что качество важнее своевременной сдачи продукта. Но все мы знаем, что такие проекты — большая редкость, иначе бы я всего этого не писал.

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

Креативная сторона программирования

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

На самом деле, считаю, что креативность — основная причина, по которой разработчики получают удовольствие от своего труда. Для меня есть нечто особенное в акте создания чего-то нового и в поиске оригинальных решений в ответ на вызовы; поэтому я и ощущаю призвание к разработке ПО, и не думаю, что я один такой. «В конце концов, если они уже все для себя решили, то зачем им я?»  — думалось мне. Мой опыт подсказывает, что всякий раз, когда мне доводилось работать в условиях, где соблюдался строгий и неизменный  «набор практик»(будь то технологический стек, процессы, регламентация, и  т.д.)  —  то eсть, чем меньше простора для творчества у меня было — тем меньше меня увлекала такая работа. С другой стороны, меня гораздо сильнее наполняла, воодушевляла такая работа (в которой я был и наиболее продуктивен), где было сравнительно немного директив сверху, оставался простор для творчества, и мне доверяли самому принимать технические решения.

Некоторым кажется, что можно просто знать идеальное решение априори (заранее), еще не написав ни единой строки кода. Важно отметить, что дополнительная творческая свобода приводит к тому, что на пути к достижению решения неизбежно будет больше проб и ошибок  —  и это нормально. Я, напротив, настаиваю, что при творческом процессе путь к открытию решения поставленной задачи (это касается не только ПО) требует повозиться: невозможно заранее все знать наверняка; напротив, вы учитесь на практике, постепенно перебирая все новые варианты и придерживаясь тех, что работают, оттачивая свое решение (и, возможно, постепенно сдавая его заказчикам, если вы работаете по «гибкой» методологии) пока вы не будете им довольны.

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

Кроме того, как и в случае с другими творческими занятиями, при программировании полезно практиковать стратегическую прокрастинацию  —  этот термин впервые предложил Адам Грант, утверждающий, что часто не удается креативить по требованию, а, напротив, креативность приходит как «push-уведомление» от некого процесса, работающего в фоновом режиме у вас в голове:

Прокрастинация не всегда подпитывает креативность: если сотрудник не обладает уверенной мотивацией решить крупную проблему, то из-за пробуксовки просто отстает. «Регулярно прокрастинирующие сотрудники обычно уделяют больше времени дивергентному мышлению, и кураторы чаще оценивали их как более творческих по сравнению с коллегами. “Originals: How Non-Conformists Move the World” Однако, если человек достаточно увлечен делом и выдает новые идеи, то, отложив задачу, приходит к более творческим решениям».
— Грант, Адам.

Опять же, это не обрадует сторонников централизованного планирования, стремящихся предусмотреть и измерить каждую минуту в проектах по разработке ПО.


Млечный путь, Марс и метеор

Мастерство создания программ

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

Для вас качество важнее количества, поскольку вы не хотите прослыть автором говнокода, даже если бы могли удовлетворить продакт-менеджера, придав вашей программе внешний лоск, а внутри нашпиговав ее кучей гнусных сюрпризов  — такой подход я называю Киндерсюрпризной Разработкой. Поскольку вы — мастер, качество вашей работы говорит о вас. Вы знаете, что уделить делу достаточно времени и написать хорошую программу — это правильно, поэтому противитесь прессингу «делай быстрее», так как знаешь, что чем больше костылей наставишь сейчас, тем недолговечнее получится твой код, и тем больше проблем с ним будет по ходу дела.


Глазки кровоточат

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

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

На практике это выражается в подобных вещах:

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

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

Ваши прогнозы ошибочны

Если решали — то просто выдадим вам результат».
— Рон Джеффрис, Движение NoEstimates
«Даже при наличии четких требований — а таковых, по-видимому, никогда не бывает —  все равно практически невозможно просчитать, сколько времени уйдет на конкретную работу, поскольку мы никогда не решали данную задачу ранее.

Софтверные проекты — это Сложные Системы: они создаются людьми, а поэтому несут отпечаток межличностных отношений, мотивации, коммуникативных проблем и человеческой психологии в целом —  все это весьма сложно смоделировать и количественно выразить в таблице, если вас интересует мое мнение. Итак, софтверные проекты очень сложно моделировать (и, следовательно, прогнозировать). Лучше всего это объясняет Нассим Талеб в своей книге «Антихрупкость»:

«Нелинейный» означает, что когда вы удваиваете, например, дозу лекарства или количество работников на заводе, отдача будет не в два раза больше, а либо намного больше, либо намного меньше. «Сложные системы отличаются большой взаимозависимостью (которую трудно распознать) и нелинейными реакциями. Нельзя сказать, что два уик-энда в Филадельфии в два раза приятнее, чем один, – это я могу утверждать по своему опыту...».
— Нассим Николас Талеб, «Антихрупкость»

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

Поэтому на оси времени, которое движется слева направо, ошибки скапливаются справа, а не слева. «Время не бывает отрицательной величиной, а значит, трехмесячный проект не может быть реализован за нулевой или отрицательный временной промежуток. Но в реальности все не так».
— Нассим Николас Талеб, «Антихрупкость»
Будь неопределенность линейной, мы бы видели, что некоторые проекты завершаются существенно раньше срока (как мы иногда прилетаем на место намного раньше, а иногда намного позже).

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


Хороший вопрос

Вот несколько примеров, демонстрирующих нелинейность разработки ПО и возникающие при этом циклы обратной связи:

  • Как-то раз вы предположили, что API, с которым требуется связываться, принимает accountId, но на самом деле он принимает лишь memberId. Добавляем к ориентировочному сроку 4 дня, нужные на рефакторинг кода API — после чего, в свою очередь, потребуется отдельное ревью, на которое мы добавим еще 2 дня.
  • Задача, которую мы рассчитывали решить за 2 дня, растягивается на неделю, поскольку в процессе ревью один из коллег принуждает вас (и правильно делает) рефакторить и оптимизировать отвратительный фрагмент кода, давно ждавший своего часа.
  • Вспомните ту задачу-одноходовку, когда требовалось реализовать всего одну новую возможность. Но оказалось, что для этого нужно обновить зависимость, на что ушло 4 дня, а эта операция спровоцировала цепную реакцию с обновлением других зависимостей и целый ворох зависимостей при сборке.

Мы облажались?

Мы просто по инерции продолжаем играть в эту игру с оценками и планированием, просто чтобы уверить себя: якобы мы контролируем ситуации. Но на самом деле ничего мы не контролируем; опыт показывает, что софтверные проекты непредсказуемы. Поэтому я думаю, что лучше сосредоточиться на деле, а не на планировании  — #NoEstimates, кто со мной? Однако, конечно же, во многих организациях это не прокатит: «Нельзя просто так взять и позволить инженерам заправлять балом, чтобы никто их не контролировал. Должна быть отчетность!». Я понял.


Вы так не говорите?

Думаю, это сводится к сокращению разрыва между миром таблиц и миром IDE так, чтобы обеспечить инженерам максимум креативности, гибкости и свободу проявлять мастерство, однако, в то же время, ответственно придерживаться обещанного и оправдывать ожидания стейкхолдеров проекта. Что же тогда делать? Это работа непростая, но необходимая. Технический менеджер (Engineering Manager) — лучший специалист по наведению таких мостов, который также может амортизировать разрыв между двумя мирами. Вот как хорошо о ней рассказывает в своей статье Аарон Лонгуэлл:

Они словно рычажная подвеска, которую тянут в разные стороны: защелкнуться может с обеих сторон. «Поскольку технические менеджеры обитают на границе между бизнесом и технарями, именно им приходится улаживать противоречия между ожиданиями и реальностью. Если инженерные доводы перевесят деловые, то прощайте бюджет и дедлайны. Если побеждает бизнес, то разработчиков загоняют до смерти. Успешный менеджер софтверных проектов находит способы действовать гибко; уступать, не ломаясь, и постепенно разруливать трения. В любом случае — провал. Подход «лидерство как служение» может помочь вам обрести такую гибкость».
— Аарон Лонгуэлл, Why Software Development Requires Servant Leaders

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

Лучше давать нечеткие сроки, например, «три-пять недель». Еще один «трюк», которым лично я пользовался на посту менеджера — не называть конкретных дат, поскольку они неизбежно превращаются в жесткие дедлайны. В таком случае вы не лукавите, общаясь с коллегами, а команде обеспечиваете гибкость сроков, которая понадобится для разрешения неизбежных непредвиденных проблем, которые возникнут. В таком случае при приближении такого зыбкого дедлайна вы добавляете: «в апреле или в мае», что легко трактуется как «Между 15-м апреля и 3-м мая» в начале апреля, около 10-го апреля может превратиться в «К 20-му апреля» и т.д.

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

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

О переводчике

Перевод статьи выполнен в Alconost.

Переводчики-носители языка, лингвистическое тестирование, облачная платформа с API, непрерывная локализация, менеджеры проектов 24/7, любые форматы строковых ресурсов. Alconost занимается локализацией игр, приложений и сайтов на 70 языков.

Мы также делаем рекламные и обучающие видеоролики — для сайтов, продающие, имиджевые, рекламные, обучающие, тизеры, эксплейнеры, трейлеры для Google Play и App Store.

Подробнее

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть