Про декомпозицию неделимых задач
В вашей работе встречаются задачи, которые занимают несколько спринтов просто потому, что выглядят неделимыми? Я знаю, что с ними делать. Особенно, если это касается разработки.
Многие статьи про декомпозицию описывают горизонтальный (по типам работ) и вертикальный (по пользовательскому функционалу) способ разделения задач.
И хотя предпочтение отдаётся второму варианту (из-за возможности быстрее получить обратную связь от заказчика и т.д.), ряд проблем остаётся «за скобками»:
- выделенная пользовательская фича может по-прежнему не помещаться в итерацию (спринт);
- некоторые задачи невозможно декомпозировать без предварительной аналитики, работа над которой займёт неопределённое время;
- работа над пользовательским функционалом требует предварительной подготовки (настройки стендов и пр.), которая также нуждается в декомпозиции и т.п.
И, несмотря на то, что некоторые задачи кажутся неделимыми - в данной статье мы рассмотрим способы их декомпозиции.
Содержание:
Не влезающие в спринт пользовательские истории
Предположим, что некую исходную задачу команда декомпозировала на три:
- Получить отчет о товаре, указав его код в текстовом поле
- Получить отчет о товаре, выбрав его в выпадающем списке
- Получить отчет о товаре (выбрав его в выпадающем списке) на электронную почту.
С одной стороны, в каждой новой версии пользователь получает приращение функционала.
Однако, предположим, что первая же задача «не помещается» в спринт: оценка задачи сильно превышает возможности команды на одну итерацию.
В такой ситуации у команды есть несколько вариантов решения данной задачи.
Непрозрачный водопад
- Затраты на ведение бэклога: низкие
- Предсказуемость времени поставки: низкая
- Промежуточные результаты: отсутствуют
- Получение обратной связи: после реализации всего функционала
При таком подходе задача берётся в работу в исходном виде, с пониманием того, что она «переедет» в следующий спринт (один или несколько).
При этом команда может и не использовать классический waterfall в своей работе, но, с вашего позволения, я буду использовать именно этот термин, подчёркивая далёкость от итеративно-инкрементальной разработки.
Этот подход наименее затратный с точки зрения предварительного анализа задачи. Детали реализации «открываются» команде в ходе самой работы.
В свою очередь, получение обратной связи на реализованный функционал возможно только после полного завершения работ. [Команде же не нужна обратная связь пользователя на написанный код?]
Однако, из-за низкой прозрачности прогресса работы над задачей, эти самые сроки завершения слабо прогнозируются.
Ну а для команд, работающих по Scrum, такой подход сильно усложняет проведение регулярного Обзора спринта (Sprint Review) из-за отсутствия промежуточных результатов.
Возможный backlog при Непрозрачном водопаде выглядит так:
- Аналитика
- Разработка отчетной формы по товару
- Тестирование
Прозрачный водопад
- Затраты на ведение бэклога: средние
- Предсказуемость времени поставки: средняя
- Промежуточные результаты: после каждой итерации
- Получение обратной связи: после реализации всего функционала
Этот подход предполагает более детальный предварительный анализ этапов реализации задачи.
Чтобы иметь возможность контролировать прогресс работы над задачей, этапы раскладываются на будущие итерации/спринты (с учётом скорости команды).
Дисклеймер: далее в качестве основной иллюстрации используется диаграмма, основанная на Диаграмме последовательности (Sequence diagram) из набора UML. Автор отдаёт себе отчет, что предложенный способ визуализации не соблюдает ряд требований к оформлению, описанных в официальной документации UML, и делает это сознательно в угоду упрощения примера.
Предсказуемость времени поставки заметно выше, чем у предыдущего подхода.
При этом, разработка ведётся «сверху вниз», из-за чего получить обратную связь на реализованный функционал возможно также только после полного завершения работ.
Если команда работает по Scrum, на Обзоре спринта возможно подведение промежуточных итогов, однако без демонстрации завершённого функционала.
Собственно, в этом и заключается главный риск использования данного и предыдущего подхода (как и любой водопадной модели): точно ли команда сделала именно то, чего хотел заказчик? (даже если это полностью соответствует ТЗ)
Порой, только глядя на результат работы команды, заказчик по-настоящему понимает чего же он хотел.
Возможный backlog при Прозрачном водопаде:
- Аналитика
- Передача id товара на back
- Поиск товара в БД
- Формирование JSON (набора данных) для передачи на front
- Формирование отчета на front для отображения пользователю
- Тестирование
Итеративно-инкрементальных подход
- Затраты на ведение бэклога: высокие
- Предсказуемость времени поставки: средняя
- Промежуточные результаты: после каждой итерации
- Получение обратной связи: после каждой итерации*
Самый сложный из всех рассматриваемых способов реализации задачи, при этом - самый эффективный с точки зрения прозрачности прогресса и скорости получения обратной связи.
Когда уже декомпозированная задача (точнее, ее часть) не помещается в итерацию/спринт и команда ищет пути решения, главный вопрос, на который требуется найти ответ: "как сделать инкремент, на который можно получить обратную связь от пользователя?" (тем самым снизив риск неэффективных затрат).
Cпойлер: решить эту задачу поможет использование «заглушек».
На первом этапе разработки реализуется (полностью или частично) функционал, связанный со взаимодействием с пользователем (например, получение запроса и возврат результата), а весь прочий функционал - эмулируется (имитируется).
Другими словами, мы делаем вид, что все «подкапотные» механизмы реализованы, при этом давая возможность увидеть итоговый результат не дожидаясь полного завершения работ. И, как следствие, имеем возможность получить от пользователя/заказчика первую обратную связь.
Разумеется, невозможно (или практически невозможно) полностью подменить весь необходимый функционал (т.е. сделать фейковый ответ системы на любой запрос пользователя).
Но, согласитесь, что после первой итерации показать заказчику отчетную форму, сформированную только по одному из всех возможных товаров - сильно полезнее в плане обратной связи и возможных переделок, чем показать код функции, просто передающей запрос с фронта на бэк.
Дальнейшая разработка происходит «снизу вверх», постепенно заменяя заглушки реальным функционалом.
С одной стороны, это может нести дополнительную нагрузку на разработчиков, т.к. реализация каждой функции требует информации о результате работы еще нереализованного функционала.
С другой стороны, такой подход позволяет проводить часть аналитики во время работы над задачей (не нужно заранее описывать интерфейс всех функций, как при классическом водопаде) и может сильно (точнее: ОЧЕНЬ сильно) облегчить работу тестировщикам.
Ввиду того, что при наращивании функционала итоговый результат не должен меняться - тестировать становится проще, плюс - тестировать необходимо только приращение.
При реализации же «сверху вниз», тестировщикам передаётся в работу весь итоговый функционал.
Разумеется, бывают ситуации, когда тестируются отдельные функции по ходу их написания, однако функциональное тестирование, при котором задействована вся система целиком (а значит - и все возможные места поломок), будет выполнено только в конце всей разработки.
По сути, при разработке «снизу вверх» с использованием заглушек, происходит перераспределение сложности между тестированием и разработкой (более подробно про это - в видео по ссылке), когда повышение сложности на этапах аналитики и разработки снижает сложность на этапе тестирования.
Таким образом, раннее тестирование вкупе с ранним получением обратной связи от пользователя заметно снижают риск масштабных переделок, а также позволяют равномерно распределять нагрузку между компетенциями в команде (ни на аналитиков, ни на разработчиков, ни на тестировщиков не "падает" весь объем работы сразу).
Возможный backlog при итеративно-инкрементальном подходе:
- Предварительная аналитика
- Отображение отчета для товара N (и только для него)
- Отображение отчета для товара N по данным, полученным от backend
- Отображение отчета для товара N по данным, реально найденным в БД
- Отображение отчета по любому товару
Дополнительная аналитика и тестирование происходят в рамках каждой из приведённых выше задач.
*Пользователь же в данном примере увидит изменение функционала только после реализации второй и последней задачи. Однако, в плане возможных переделок это сильно безопаснее, чем при водопадных подходах.
Задачи типа «Чёрный ящик»
Отдельного внимания заслуживают "чёрные ящики" - задачи, понимание сути которых приходит только во время работы над оными:
- задачи, с которыми раньше команда дела не имела;
- сложная аналитика;
- баги неизвестной природы и пр.
Соответственно, такие задачи не поддаются какой-либо оценке, а значит - сложно прогнозируется время их завершения и нагрузка команды в целом.
Главная ошибка команд при работе с такими задачами - взятие их в работу в исходном виде.
Разумеется, в этом нет злого умысла: имеет место либо отсутствие необходимости иметь прозрачность в сроках завершения работы, либо отсутствие навыка декомпозиции подобных задач.
Самым простым и действенным советом в данной ситуации будет «отрезание» от Чёрного ящика небольших понятных задач. Другими словами - выделение первых шагов решения исходной задачи.
Важно: для «отрезаемых» задач должны быть понятны критерии завершения и способы реализации (именно это будет отличать их от исходного «Чёрного ящика»):
Во-первых, это позволяет оценить задачи (тем самым делая работу и нагрузку команды более предсказуемой).
Во-вторых, реализация этих задач даёт понимание о выделении из Чёрного ящика следующих этапов работы = следующих небольших и понятных задач.
В конечном итоге Чёрный ящик перестаёт быть таковым. Завершение работы над оставшейся частью становится, как говорится, «делом техники».
Таким образом, взятие в работу только предсказуемых задач, сильно повышает управляемость рабочим процессом.
Итоги
Взятие в работу задач, которые заведомо невозможно сделать за итерацию чревато множеством сложностей:
- низкая точность оценки, и как следствие - неточное планирование;
- низкая прозрачность прогресса разработки;
- неравномерная нагрузка членов команды;
- длинная петля обратной связи от пользователя и пр.
Всё вышеперечисленное выливается в риск непопадания обозначенных сроков и возможных переделок.
Однако, даже "неделимая" на первый взгляд задача может быть декомпозирована с сохранением возможности сбора обратной связи от пользователей или заказчиков.
Помимо этого, оценка декомпозированных задач позволяет лучше планировать нагрузку команды и завершение работ в целом, а следовательно - управлять ожиданиями заказчика.
А так как оценка - инструмент требовательный, качественная декомпозиция - далеко не единственный фактор, влияющий на ее точность. Именно по этой причине я указал Среднюю предсказуемость времени поставки функционала для Прозрачного водопада и для Итеративно-инкрементального подхода.
Ну а чтобы повысить свои шансы на то, чтобы ваша предсказуемость стала Высокой - рекомендую подробную статью про Оценку (а точнее - про инструменты, зависящие от правильного и неправильного использования оценок задач).
P.S. А еще Диаграмму последовательности можно использовать для описания связей между командами. Подробнее - в этом видео.