The principles of product development flow. #СМС23

Понимание, что разработка программного обеспечения / продуктовая разработка это стохастический / вероятностный процесс это самая важная мысль, которая содержится в книге. Собственно автор указывает, что на производстве ничего вероятностного нет, все процессы очень предсказуемы, и следовательно lean производство / принципы Goldratt очень успешно, в тоже время, если рассматривать софтверную разработку как производство и применять те же принципы, результатов не будет, все из за вероятностности процессов. Соответственно, много идей в книге посвящено работе с неопределенностью/случайностью, а некоторые принципы перекликаются с темами Насима Талеба (например, что нужно ограничивать величину проигрыша, но оставлять величину выигрыша неограниченной, random walk и как его ограничивать, идеи децентрализации и прочее).

Очереди и batch size.

Автор вводит несколько объектов внимания, такие как очереди работ (queues), размер работ (batch size) и загрузку производственных мощностей / ресурсов (capacity utilisation).

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

Как считать стоимость задержки это отдельный интересный вопрос. Автор использует расчеты, как будто ценность каждой фичи / item можно узнать заранее. Я не встречал такого подхода в продуктовой разработке (может быть я не работал в настоящих командах где финансовый успех каждой фичи просчитывается в денежном выражении) . Если же говорить о проектной деятельности, то про это отлично написано тут: Cost of Delays In Software: How do you Calculate it? | Cprime Blog Те если мы говорим про заказную разработку, то стоимость задержки это стоимость части проекта, которая еще не выпущена в продакшн. Если мы работает с водопадной моделью, и весь проект еще не в продакшн, то стоимость задержки равна стоимости всего проекта! Вот она польза incremental delivery! Если же мы находимся в ситуации какого то strict deadline, то incremental delivery не обязательно поможет, и возможно имеет смысл рассмотреть изменения скоупа проекта.

Уменьшение batch size - это главный и самый действенный способ уменьшения очередей, так . Интересно, что размер очереди и batch size описывается U функцией, и значит с batch size не страшно экспериментировать, потому что его изменения у основания функции не даст значительного изменения размера очереди. The rule of thumb - уменьшайте размер batch size на 30% от задуманного размера.

Оптимизация очередей
  • Один из способов это уменьшение загрузки ресурсов. Существует интересная нелинейная зависимость между загрузкой ресурсов и длинной очереди, особенно в районе 80-100 процентов загрузки. В этом диапазоне длинна очереди растет как квадрат увеличения загрузки. Соответственно, уменьшая загрузку на небольшое значение, можно уменьшить длину очереди на существенное значение. В реальном жизни это выражается в том, чтобы не перегружать людей работой, особенно когда работе представляет собой случайный процесс, так как неожиданно сложная задача / неожиданность может остановить поток работ и создать очередь работ.
  • Уменьшая размер работ. Уменьшая размер работ, уменьшается время обработки работ, что увеличивает прохождение работа, и это уменьшает кол-во работ в очереди те уменьшает очередь работ. Размер работ можно уменьшать разными способами, но главное, чтобы эти работы можно было делать независимо разными обработчиками/серверами/людьми/ресурсами.
  • Уменьшить стоимость очереди можно и без уменьшения размера очереди используя “дисциплину” планирования работ внутри очередей, . Например, начиная делать те работы, которые имеют максимальную стоимость задержки, и потом, приоритизировать те, которые находятся на критическом пути.
Вариативность / Variability / Отклонение от среднего / Накопление ошибки

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

Самое важно это пример про 9 очередей и 9 серверов (обработчиков). Меньшая вариативность по времени обработки очереди будет если 9 серверов по очереди будут обслуживать одну очередь, так как в таком случае вся очередь замедлиться на какое то время но будет продолжать двигаться.

Далее существует несколько способов уменьшить вариативность:

  • Pooling. По сути это то, как оцениваются проекты и большие фичи, разные части проекта или фичи эстимируюются отдельно. Так как оценка каждого элемента это независимая случайная величина, то эти случайности (те переоценки и недооценки) суммируются и получается вполне предсказуемая группа работ. Отсюда важно никогда не заниматься детальным планированием!
  • Covariance. Это про контр балансирование вариативности. Например, путем увеличение вариативности загрузки ресурсов, можно балансировать вариативность времени исполнения. Как пример, если есть компаунда тренированная и в разработке и в тестировании, то при увеличения работ на этапе тестирования, можно уменьшить загрузку разработчиков для разработки и увеличить ее для тестирования.
  • Reuse. Это то, что я активно пропагандирую в своей компании. Переиспользование компонент, модулей, дизайна, все это нелинейно уменьшает вариативность времени разработки, особенно если речь идет не про команду, а про компанию, где все команды могут переиспользовать общие ресурсы.
WIP constraints / Ограничение работ в обработке

Ограничение работ в обработке (не смог более точно перевести), ведет у уменьшению очередей, что в свою очередь ведет к уменьшения стоимости задержки.

Существует 2 основных способа управления WIP для реакции на растущие очереди:

Контролирование работ на входе / Arrival / demand controls и контролирование работ на выходе / Exit / supply control. Контролирование работ на входе быстрее приводит к уменьшению очереди.

Примеры практик контролирования работ на входе:

  • Просто убрать работы скопившееся на входе или оставить их на предыдущем этапе (upstream) потока работ
  • Убрать проекты, которые приносят наименьшую пользу
  • Убрать некоторые требования (например, перенести их в след фазу)

Примеры практик контролирования работ на выходе:

  • Resource pulling. Добавить экстра ресурсы для борьбы с очередью. Из за нелинейности кривой между длинной очереди и загрузкой ресурса, даже если ненамного уменьшить загрузку ресурса, можно сильно уменьшить длину очереди
  • Use parts time resource for high variability tasks on the critical path. Это разновидность правила выше
  • Pull high power resources for high availability tasks. То, что используется в моей компании и особенно со мной постоянно. Есть набор звезд и их периодически привлекают спасать компанию, закрывая какие то непонятные и невыполнимые задачи
  • Have T-shaped people. Такие люди обычно являются тим лидами или находятся в службе поддержки, так как им нужно иметь возможность решать многие классы задач.
  • Have cross trained people. Кросс функциональные команды - это то, что проповедует agile методологии, но их сложно создать, особенно в заказной разработке. Я как раз занимаюсь проектом автоматизации таким образом чтобы каждый член команды мог занять роль тестера автоматизатора.

Существует также еще одна практика mixed - это дисциплина очередей, когда задача внутри очереди помечается по признаку того, какие работы в основном будут сделаны (например design heavy feature). В таком случае если существует стадия дизайна простаивает, то эту фичу нужно отправлять именно туда.

Поток / Flow и управление потоком

Собственно поток работ - это и есть основной объект внимания операционного менеджмента. Основная задача, это убрать очереди на всех запрудах/этапах/upstreams

Существует 3 основных способа работы с потоком: работа с очередями, работа с вариативностью, и работа с последовательностью работ.

Работа с очередями это все то, что было описано ранее, работы с batch size, работа с загрузкой ресурсов. Кроме этого, визуализации работ и очередей это то, что рекомендует автор, что в эпоху Trello и Jira звучит как само собой разумеющееся.
Работы с вариативностью - это то, что легче всего масштабировать на уровне компании, особенно в части работы со встречами и ревью. Автор выделяет понятия cadence и понятия synchronisation.

Cadence / Ритм нужен, чтобы обнулять накопленную вариативность. Например, каждый раз, когда нужно создавать встречу в календаре с большим кол-вом людей нужно тратить время (увеличивать time variance) на его организацию, проще создавать такие встречи циклично, например раз в неделю. Тогда затраты на организацию и проведения встречи будут минимальны.

Synchronisation - это про совмещение нескольких событий. Например, делать ревью проекта группой экспертом, вместо того, чтобы делать его каждым экспертом по отдельности - гораздо эффективнее, так как не накапливается вариативность, тут же можно получить быстрый feedback.
Особенно здорово, это совмещать small batch size и cadence вместе, например не делать ревью проектов один раз в 3 месяца для всех проектов, а делать его раз в 2 недели для части проектов причем тратя пропорционально меньше времени. Это приведет к тому, что вариативность по проверяемым проектам не успеет накопиться.

Работа с последовательностью работ. Собственно тут про то, что если все работы предсказуемы, то фабричный FIFO работает идеально. Однако если у нас случайный процесс, то лучше использовать методы вроде weighted shorts job first. Тут главная задача это определить веса работ правильным образом (все та же задача определения cost of delay)