Проблема движения задачи от бизнес-идеи до реализации - не новая, и каждая команда пытается решить её (более или менее успешно) в соответствии со своим опытом и пониманием этой проблемы. Существующие методологии, призванные помогать, зачастую только запутывают. Чтобы срезать острые углы и недопонимания, организуются планирования и груминги (grooming), которые сжигают рабочее время команд и иногда запутывают ещё больше.
О чём это руководство?
Главная задача этого руководства - организовать бесшовное и бесконфликтное движение задачи от бизнес-требований до технической реализации. Мы опустим такие важные элементы разработки, как бурные обсуждения и даже груминги, сосредоточив внимание на исполнении специалистами своих обязанностей и передаче задачи дальше, в соответствии её с жизненным циклом. Я исхожу из того, что навыки членов команды соответствуют их ролям, и что все выполняют свои задачи на приемлемом уровне.
Этапы решения задачи
Можно выделить четыре основных этапа решения бизнес-задачи, которые сменяют друг друга в рамках задачи: бизнес-требование, функциональное требование, техническое задание и техническая реализация.
Бизнес-требование - это описание задачи в том виде, в котором она получена от бизнеса. Для этого применяют общие понятия из предметной области продукта.
Пример бизнес-требования
Я, как пользователь, хочу зайти на сайт, используя свои логин и пароль.
Я, как пользователь, хочу загрузить свою фотографию в профиль и чтобы она отображалась на аватарке.
Функциональное требование - это описание функции, выполняемой приложением, в виде последовательности действий пользователя и результата этих действий. В нём описывается бизнес-требование языком, понятным для аналитика - общими понятиями из предметной области разработки.
Пример функционального требования
Функциональное требование 1:
Пользователь вводит логин и пароль на веб-странице входа и авторизуется в системе.
Функциональное требование 2:
Пользователь загружает файл, файл сохраняется в файловом хранилище.
Как мы видим из примера выше, в функциональном требовании используются сущности из предметной области веб-разработки: исчезли слова "сайт", "фотография", "аватар", появились слова "страница", "файл", "авторизация".
Техническое задание - это описание конкретных шагов, с помощью которых разработчики должны реализовать функциональное требование. Для описания технического задания необходимо знать не только предметную область, но и технические детали реализации приложения.
Важно: задача может быть взята в работу разработчиком только в состоянии технического задания. Бывают ситуации, когда разработчик самостоятельно преобразует функциональное требование в техническое задание, но в таких случаях он действует не как разработчик, а как системный аналитик - такие ситуации будут описаны ниже.
Пример технического задания
Реализовать хранение данных в таблице users, включающей в себя следующие поля:
Поле | Обязательность | Тип |
---|---|---|
id | true | uuid |
login | true | varchar(512) |
password | true | varchar(512) |
description | false | text |
Пароль должен храниться в зашифрованном виде, метод шифрования SHA512.
Техническая реализация - это описание конкретных изменений в коде, сделанных разработчиком в рамках выполнения технического задания.
Пример технической реализации
В рамках задачи было реализовано следующее:
Созданы таблицы users, authorities.
Создан эндпоинт: /users/login
Реализована логика авторизации пользователя.
Описание технической реализации является верхнеуровневым и обычно описывается разработчиком в комментарии к задаче.
Теперь, когда мы разобрали компоненты жизненного цикла задачи, давайте обратим внимание на основные роли аналитика.
Основные роли аналитика
Их две: бизнес-аналитик и системный аналитик.
Бизнес-аналитик работает с бизнес-задачами и функциональными требованиями, на стыке предметной области продукта и общих понятий предметной области разработки.
Например, если идёт речь о разработке интернет-магазина, бизнес-аналитик хорошо понимает, как работает интернет-магазин, как происходит оформление заказа, доставка, клиентская поддержка. Он знает основные категории товарной номенклатуры.
В то же время, бизнес-аналитик поверхностно разбирается в разработке. Он понимает, что такое фронтенд, бэкенд, как они обмениваются информацией, что такое база данных и так далее.
Бизнес-аналитик общается с заказчиком и получает от него бизнес-требования, которые он хорошо понимает в силу своих компетенций.
Системный аналитик отлично разбирается во внутренней реализации приложения. Он знает создаваемый продукт изнутри: имена таблиц базы данных, наименования полей моделей API, применяемые алгоритмы. Как правило, у него есть специальное техническое образование. Роль системного аналитика зачастую исполняет разработчик уровня Senior.
Теперь, когда мы поверхностно разобрали роли аналитиков, можно перейти к профессиональным уровням разработчиков.
Профессиональные уровни разработчиков
Существуют три профессиональных уровня разработчиков: Junior, Middle, Senior. Четвёртый уровень - Tech Lead - как правило, не участвует в выполнении задач, и его мы разбирать не будем. У каждого профессионального уровня своя глубина компетенций и, соответственно, круг обязанностей и полномочий. Профессиональные уровни разработчиков нас интересуют лишь применительно к тематике обработки и выполнения задач.
Junior-разработчик выполняет самые простые и низкоуровневые задачи. От него не требуется детальное знание предметной области продукта. Задачи, назначаемые Junior-разработчику, должны быть описаны на уровне очень подробного технического задания.
Middle-разработчику, в зависимости от своей квалификации внутри профессионального уровня (low, middle, high), ставятся технические задания разной степени детализации. Если для low middle нужно расписывать всё так же подробно, как и для junior, то для high middle достаточно описать верхнеуровнево. Middle-разработчик обычно слабо разбирается в предметной области продукта, и от него не требуется разбираться очень хорошо.
Senior-разработчик способен не только выполнить задачи любой сложности, но и преобразовывать функциональное требование в техническое задание. Он обязан хорошо разбираться в предметной области продукта.
Мы разобрались с ролями специалистов и можем перейти к самой главной части поста - трансформации задачи из одного состояния в другое.
Трансформация задачи
Трансформация бизнес-требования в функциональное требование
Функциональное требование - это детальное описание поведения системы, на основе бизнес-требований: функции приложения, с которыми взаимодействует пользователь (видит на экране, кликает, вводит данные и так далее). Функциональное требование делится на две части: функцию и поведение. Функция описывает, что делает система, поведение - как система исполняет эту функцию.
Пример трансформации бизнес-требования в функциональное требование и декомпозиции его на функцию и поведение:
Бизнес-требование:
Я, как пользователь, хочу зайти на сайт, используя свои логин и пароль.
Функциональное требование:
Пользователь авторизуется в системе.
Функция:
Авторизация в системе.
Поведение:
Система получает от пользователя логин и пароль через специальную форму авторизации. После чего, система проверяет логин и пароль на наличие в базе данных. Если пара логин-пароль существует, система возвращает положительный ответ и авторизационный токен.
Как мы видим из примера выше, функциональные требования включают в себя оба компонента: функцию и поведение. Функциональные требования описаны как можно более детально, но не выходя за границы общих понятий предметной области разработки.
Трансформация функционального требования в техническое задание
Техническое задание - это как можно более подробное описание будущей реализации функционального требования. Оно включает в себя описание всех компонентов, которые будут созданы или изменены в рамках работы над задачей - объекты, эндпоинты, имена полей, алгоритмы и т. д.
Если в техническом задании описывается эндпоинт, нужно описать все его значимые атрибуты: HTTP-метод, иерархическую часть пути, переменные пути, параметры запроса, входящие и исходящие объекты.
Если в техническом задании описывается объект / структура данных, то необходимо указать имена полей, их тип, обязательность, описание поля (что оно делает).
Если присутствует алгоритм, его нужно описать предельно точно, чтобы у разработчика не возникло разночтений.
Если описано преобразование из одного объекта в другой, то сопоставление нужно описать предельно чётко, по каждому полю, с их типами и обязательностью.
Давайте возьмём функциональное требование из примера выше и преобразуем его в техническое задание:
Функциональное требование:
Пользователь авторизуется в системе.
Функция:
Авторизация в системе.
Поведение:
Система получает от пользователя логин и пароль через специальную форму авторизации. После чего, система проверяет логин и пароль на наличие в базе данных. Если пара логин-пароль существует, система возвращает положительный ответ и авторизационный токен.
Техническое задание:
Реализовать авторизацию пользователя, следующим образом:
Создать таблицу users в базе данных, схема main:
Имя поля | Тип | Описание |
---|---|---|
id | uuid primary key, генерация на стороне базы данных | Идентификатор пользователя |
login | varchar(512), индексация поля | Логин пользователя |
password | varchar(128) | Пароль, зашифрованный в формате sha256 |
Создать эндпоинт авторизации.
HTTP-метод: POST
Path: /users/login
Тело запроса:
Имя поля | Обязательность | Тип |
---|---|---|
login | да | String |
password | да | String |
Ответ (в случае авторизации):
HTTP-статус: 200
Объект AuthToken:
Имя поля | Обязательность | Тип |
---|---|---|
authToken | да | String |
refreshToken | да | String |
authTokenExpirationTime | да | Int |
refreshTokenExpirationTime | да | Int |
Алгоритм работы авторизации:
При получении запроса на авторизацию, сервис ищет пользователя в таблице users по полю login. Если пользователь не найден, сервис возвращает статус 401 Unauthorized, с сообщением "Пользователь не найден". Если пользователь найден, сервис создаёт хэш-сумму полученного пароля и сличает с пользовательским паролем из базы данных. При несовпадении паролей, сервис возвращает HTTP-статус 401 Unaurhorized, с сообщением: "Указанный пароль не верен". При совпадении паролей, сервис генерирует авторизационный токен и рефреш-токен и возвращает объект AuthToken.
Мы разобрались, какие бывают состояния задачи и как происходит трансформация из одного состояния в другое. Но кто будет этим заниматься?
Распределение полномочий в команде
Чтобы организовать бесшовное и бесконфликтное движение задачи по всем стадиям от бизнес-требований до технической реализации, команда должна быть не только достаточно укомплектованной, но и, по возможности, не "переполненной" специалистами.
Состав команды должен быть сбалансирован так, чтобы было кому брать задачу в текущем состоянии и трансформировать в следующее. Мы уже знаем, что:
Senior-разработчик преобразует функциональное требование в техническое задание. Это значит, что он может брать на себя обязанности системного аналитика.
бизнес-аналитик преобразует бизнес-требование в функциональное требование.
Разработчик (любого уровня) реализует техническое задание.
Таким образом, чтобы команда считалась укомплектованной, в ней должны быть специалисты со всеми тремя вышеописанными компетенциями.
Идеальный вариант:
Бизнес-аналитик + системный аналитик + разработчик.
В этом случае, каждый на своём месте и каждый делает свою работу. Но может быть и такой вариант:
Бизнес-аналитик + Senior-разработчик.
В таком случае, Senior-разработчик будет брать на себя обязанности системного аналитика и сам же реализовывать полученное техническое задание. Да, объём обязанностей смещается в сторону разработчика, но такой вариант выглядит вполне рабочим.
Впрочем, если аналитик может быть и бизнес-, и системным, то возможен и такой вариант:
Аналитик (бизнес+системный) + разработчик не ниже уровня Middle.
При любой из этих комбинаций, задача не подвиснет из-за разрыва в компетенциях, её всегда будет кому взять в текущем состоянии и трансформировать в следующее.
Но как быть, если в команде есть и системный аналитик, и Senior-разработчик? Возникает риск конфликта компетенций: трансформировать функциональное требование в техническое задание под силу обоим специалистам, но у каждого будет разное видение.
Я рекомендую отдавать приоритет разработчику, поскольку техническая реализация и её дальнейшая поддержка будет на его ответственности. Но тогда он должен подробно описать техническую реализацию, а системный аналитик - с ней ознакомиться, чтобы быть в курсе реализаций в коде и быть готовым перехватить задачи по системной аналитике, в случае необходимости.
И напоследок. Про груминги и планирования. Пьеса в двух актах.
Итак, наша команда укомплектована всеми необходимыми специалистами в самом, пожалуй, распространённом составе. Есть представитель бизнеса - Владелец Продукта. Есть бизнес-аналитик. Есть Senior-разработчики (фронтэнд и бэкенд).
Посмотрим, как они работают.
Действующие лица:
Владелец продукта (он же, скрам-мастер), Бизнес-аналитик, Senior Backend Developer, Senior Frontend Developer.
Акт I. Груминг.
Владелец продукта: Я хочу, чтобы в будущем спринте были реализованы фичи А и Б.
Бизнес-аналитик: Я обсудила с владельцем продукта эти фичи заранее. Я создала две Stories, А и Б. Я описала в них функциональные требования. Коллеги-разработчики, посмотрите, пожалуйста, эти фичи и декомпозируйте их.
Senior Backend Developer, Senior Frontend Developer (хором): Спасибо, берём в работу.
Владелец продукта: Всем спасибо, увидимся через 3 дня.
Акт II. Планирование.
Владелец продукта: Коллеги-разработчики, как ваши дела?
Senior Backend Developer, Senior Frontend Developer (хором): Мы обсудили каждую фичу, изучили функциональные требования и декомпозировали их в технические требования, создали подзадачи. Мы оценили каждую подзадачу в сторипоинтах и готовы к планированию.
Владелец Продукта: Отлично, коллеги. Спасибо, что подготовились к планированию. Сейчас мы за 15 минут раскидаем подзадачи по исполнителям и пойдём работать дальше.
Занавес.
В этой пьесе нет сильной драматургии. В ней нет даже конфликта. Потому что большая часть работы была сделана исполнителями заранее, и они пришли подготовленными. Организация грумингов и планирований - хоть и напрямую касается жизненного цикла задачи, но всё же, тема для отдельного поста. Возможно, мы поговорим об этом позже.