Software: Bears, Bulls & Swaps
«А давайте напишем систему так, чтобы, когда нам что-то понадобится, оно там уже было»
Один из моих первых работодателей.
Разработка ПО для меня, в первую очередь, — это борьба со сложностью. Со сложностью создания модели прикладного домена, выбора инструментария, построения ортогонального интерфейса, адаптации к новым требованиям, борьба со сложностью поддержки и модификации системы.
И если сложность прикладного домена можно рассматривать как константу или данность, то сложность, порождаемую процессом разработки, можно и нужно контролировать.
Result vs Process
Если обратиться к классике, то целью разработки ПО являет продукт, решающий задачи пользователя, с максимально приемлемыми значениями внешних факторов качества: #correctness, #robustness, #extendibility, #reusability и т.д. [Бертран Мейер. Объектно-ориентированное конструирование программных систем]. Это то, что покупает заказчик.
Перемещаясь по оси результата, разработчики сталкиваются со сложностью домена: рассчитать риски для финансовых инструментов, удалить вырожденные треугольники перед 3D-печатью, выдерживать нагрузку 100К пользователей и т.д.
Но если дополнительно рассмотреть сам процесс разработки, то здесь появляется одна из ключевых особенностей ПО: высокая вариативность. Количество возможных способов достижения результата огромно.
И как следствие, разработка движется уже не просто по прямой результата, а из точки A в точку B, а точнее, в некоторую область, так как с течением времени может меняться не только процесс разработки, но и сама конечная цель. И чем сложнее ваши процессы, тем большее влияние они оказывают на конечный результат.
На практике, достичь точки В из точки А по прямой невозможно. Представьте, что вы с первого раза создаёте «правильную» иерархию классов, все и вся покрываете тестами, все этапы сразу автоматизируются не в ущерб полезному функционалу, вы всегда называете переменные «правильными» именами, ваша документация — актуальна, а главное — заказчик не меняет требования к конечному продукту.
Bears
Когда деревья были выше, а трава зеленее, ПО разрабатывали программисты. Они, ориентируясь на технические моменты систем, выбрали для себя наиболее комфортную стратегию: сначала архитектура, потом специализация и разработка конечного функционала, необходимого заказчику. Это очень похоже на стратегию из одного мультфильма: «Лучше день потерять, зато потом за 5 минут долететь».
Спецификации, диаграммы, определение интерфейсов, несколько этапов утверждений и только после — реализация в базисе согласованной модели.
Ахиллесова пята данного подхода в том, что пока вы разрабатываете архитектуру, конкуренты уже вышли на рынок с половиной функций, работают с пользователями и получают прибыль.
Bulls
Нарастающие требования к скорости разработки и её объемам привели к необходимости пересмотра самих методов построения ПО.
Гибкие методологии разработки обещали Грааль — фокусировку на результате, постановку во главу угла потребностей пользователя, сокращение цикла разработки, то есть лекарство от всех болезней. Все это происходило на фоне улучшения инструментов: языков программирования, сред разработки, библиотек и пр. Более того, они уменьшали планку входа и стоимость.
Важно понимать, что чаще всего, это возможно за счёт экономии на разработке архитектуры (путём привлечения готовых компонентов), рефакторинге, R&D и уровне разработчиков.
Краеугольной проблемой здесь является то, что частое игнорирование необходимости работ по улучшению внутренней структуры программной системы приводит к постоянному накоплению технического долга и как следствие — к поэтапному смещению в область легаси-продукта.
Попробуйте обсудить во время планирования и добавить в спринт следующую историю: «Как разработчик, я должен произвести рефакторинг класса А с целью возвращения технического долга первого спринта».
Почему Agile не захватит мир? Потому что велик соблазн закрыть глаза на «прикрутки», недочёты в архитектуре и сказать: «А давайте добавим все это в список задач и вернёмся к нему, когда будет время».
Это время не наступает никогда.
Swaps
«Software eats world» и сейчас сложно определить, что очередная идея программной системы стоит того, чтобы быть принятой в разработку. Очень часто сложность информационной среды не позволяет сказать с уверенностью, что систему вообще можно реализовать в заданные сроки, с заданными функциями и она сможет решить существующие задачи эффективнее. Идея быстро создать работающий прототип, отвечающий на ключевые вопросы, выглядит более чем разумно: это небольшие инвестиции с максимальным результатом.
Подвох здесь в том, что одну и ту же часть работы нужно будет выполнить дважды: сначала в базисе прототипа, а потом как часть продукта и, что более важно, не все тестируемые идеи оправдают затраты.
R&D-отделы компаний работают по этому принципу, понимая что это плата за возможность «пощупать» идею и «нащупать «Next Big Thing».
99% процентов PoC останавливаются в точке E (см. график выше).
Fractals
Описанные выше стратегии — это всего лишь строительные блоки. Каждый проект уникален, более того, оптимальный ход разработки может существенно отличаться в начала и в конце проекта или даже спринта, RUP тому подтверждение.
Разрабатываемая система — это комбинация этапов (задач), для каждого из которых, вы принимаете компромиссное решение в пользу затраченного времени, качества или объема работ.
Singularities
Для каждого из подходов наступает момент, когда необходимо изменить приоритеты и скорректировать движение.
Waterfall — Bear market
Точка С — переломный момент, когда от проектирования необходимо переходить к реализации полезных функций.
Что произойдёт если, позволить разработчикам продолжать двигаться в том же направлении? Проект никогда не будет закончен.
Если у вас бесконечный бюджет, то в обозримом будущем вы достигнете точки B`, с «идеальной» иерархией классов, согласованностью, но с функционалом, который безнадёжно устарел или уже стоит слишком дорого.
Agile — Bull market
Точка D — мечта любого Product Owner-а: бОльшая часть заявленных функций реализована, система не содержит ошибок класса А.
Но в этой точке, в соответствии с выбранной стратегией, накопилось множество спорных решений и недочётов, начиная с отсутствия комментариев в коде и не покрытых тестами частей, до выявленных в процессе реализации спорных архитектурных решений и пробелов в автоматизации.
Вас никто не осудит, если вы просто дотянете до точки B`. Потом будет работа над новой версией, или даже другой продукт, а может и работа в новой компании.
Swap — Hedging risks
Точка E — момент внутренней демонстрации PoC. На этом этапе должны быть проверены основные гипотезы: интерфейсы разных систем могут быть состыкованы, сервер выдерживает необходимую нагрузку и т.д.
После это момента, код из PoC может быть использован только как демонстрация, но не как базис для дальнейшей разработки. В противном случае, с вероятностью близкой к 1, вы никогда не достигнете точки B.
PoC позволит вам начать разработку с «чистого листа», точки F, с пониманием того, как система должна быть построена. Вы не начинаете с нуля, а как бы из некой условной точки A` в прошлом. Здесь нужно быть аккуратным и не попасться на крючок «эффекта второй системы» — перегрузить архитектуру, базируясь на положительном результате PoC.
Balance
«Выбор всегда заключён между тем, что легко, и тем, что правильно».
Резюмируя сказанное выше:
— смещение в область процесса порождает сложность завершения проекта в срок;
— перекос в сторону результата накапливает сложность технического долга;
— всё это происходит в процессе работы со сложностью прикладной задачи;
— и на фоне постоянного усложнения внешней среды (IT).
Ключ к созданию качественного ПО лежит в плоскости эффективного объединения двух взаимосвязанных векторов процесса и результата и в последовательной корректировке общего вектора движения.
В идеальном случае, для каждой задачи на проекте нужно сопоставить оценку из интервала -N..N. Отрицательное значение — для задач, сфокусированных на процессе, положительное — для задач, ориентированных на результат.
Более реалистичный сценарий состоит в том, чтобы маркировать таким образом только те задачи, которые имеют явные перекосы в сторону процесса (рефакторинг класса) или результата (прикрутка перед демо). Это позволит не только видеть баланс между ними, но и иметь доводы для разрешения споров и коллизий интересов, которые будут базироваться на объективных данных, а не на суждениях и предпочтениях.
Сбор такой статистики позволит выявлять перекосы в ту или иную сторону и принимать взвешенные решения, а поддержание данной метрики в области нуля позволит быть уверенным, что баланс между тактикой и стратегией, процессом и результатом соблюдается.