Хождение по воде и разработка по спецификации легки, если и обе заморожены
Эдвард В. Берард
С самого начала моей карьеры, спецификация была больной темой. В маленькой веб-студии написание «спеки» сводилось в лучшем случае к двум-страничкам A4 с описанием нового модуля для уже работающей CMSки. Со временем я повидал и спеки как на 80 страниц от сторонних компаний в фиксированном pdf виде, так и в режиме постоянного scrumа где спека размазана по десяткам задачам в issue tracker’е.
Есть разница между спецификацией (SRS, техническим заданием), документацией и руководству по техническому обслуживанию, она в цели.
Цель спецификации зависит от фазы развития проекта:
- объяснить всем цель, причины, ограничения, scope и ожидания
- закрепить требования для этой фазы разработки
- получить оценку по времени, сложности, доступности ресурсов
- синхронизировать терминологию, поддерживать единую точку зрения для всех разработчиков
- под конец реализации, спецификация превращается в документацию — в базу знаний, карту по продукту
- автоматизировать тесты всех уровней
- запустить в оборот дальнейшие документы -user guide, release notes, white paper, интерактивную помощь, статьи в блоге
- подготовить tech manual для ремонта или интеграции системы
Scope — это треугольник ограничивающий ожидания всех сторон и напрямую влияющий на цену и деньги:
- Функциональность (сумма всех фич)
- Время выполнения
- Качество и детальность проработки
Без спецификации и чёткой черты ожиданий функиональности возникнут конфликты. С размытыми ожиданиями заказчик может добавлять в scope всё новые и новые задачи, либо ожидать нереалистично быстрых сроков, либо ожидать другое качество работы по производительности, поддержке устройств или языков.
Работая без спецификации, разработчики постоянно будут сталкиваться с новыми, ранее неизвестными требованиями. Это создаёт угнетающую атмосферу отсутствия прогресса, шаткости всего решения, страха переписывания всего проекта из-за какой-то важной мелочи. Потратив день на продумывание спецификации, можно точней сделать оценку трудозатрат (estimation), сузить конус неопределённости и снизить расходы
Содержание
Спецификация касается только фич, а не задач типа Improvement или Bug. Bug это несоответствие реализации и спеки. Improvement должен включать изменение спецификации на фазе release или code review.
Типы фич
Фичи в свою очередь различаются по глубине и влиянию на продукт. Спецификация для них фокусируется на разных пунктах и средствах донесения информации
- UI компонент (frontend). Например popup, tooltip, модальное окно, календарь, autocomplete, slider картинок
- Локальные бизнес-фичи (frontend + backend). Функционал свойственный именно этому продукту и завязанный на поведение пользователя. Например загрузка аватарок, изменение статьи, генерация excel-report’а.
- Глобальные архитектурные фичи (frontend + backend). Например навигация, переводы, error pages, permissions, email notifications. Завязаны на бизнес-фичи и инфраструктуру.
- Инфраструктурные, скрытые фичи (backend). Например мониторинг, логи, транзактивность, масштабирование серверов, асинхронные очереди, API reference
Стиль и язык
Спецификацию должен писать один автор, по возможности получая обратную связь от комманды. Это придаст спецификации однородный стиль и единую терминологию.
- Простота. Используйте минимум иностранных фраз, сленга и аббревиатур. Используйте односложные предложения.
- Понятность. Выносите упоминания протоколов, кодировок, расширений в сноски или прячьте эти детали. Приводите пример расчётов
- Неполнота. Требования не должна досконально описывать всё решение
- Согласованность. Требования не должны противоречить друг другу
- Точность и проверяемость. Избегайте:
- обобщений (every, all, everywhere, never, any, each)
- бесконечных глаголов (minimize, maximize, optimize, improve)
- неточных глаголов (support, handle)
- неточных прилагательных (easy, simple, efficient, flexible, user-friendly, superior, seamless, graceful)
- неисчислимые (few, several, many, some)
- «догадайся сам» (etc. и … , including but not limited to, where appropriate, if necessary, adequate, reasonable, sufficient, optionally)
- латынь — etc., e.g., i.e., ergo
- Однозначность.
- Избегайте двусмысленных выражений (это, который) в сложносочинённых предложениях. Например, что значит «мама / папа «? Правильно — «мама, папа или оба».
- Одна сущность — один термин, одна операция — один глагол. Минимум обобщений ( «Все варианты», «во всех местах», «Каку продукта Y» )
Версионируйте спецификацию с датами и авторами изменений. Указывайте к какой версии приложения она относится или с какой ветки она актуальна. Лучше всего документацию хранить внутри git вместе с кодом
Joel Spolsky советует разбавлять спеку крупинками юмора, что-бы она не была слишком сухой и трудночитаемой
Уровни обязательности
Некоторые спеки градируют приоритеты языком, указывая какие фичи обязательны а какие не очень:
- MUST или MUST NOT, REQUIRED, SHALL — строго обязательный функционал
- SHOULD или SHOULD NOT, RECOMMENDED — желательный функционал, но надо взвесить недостатки
- MAY, OPTIONAL — реализуется по возможности
Причинно-следственная связь
Описывая пользовательские сценарии, может встать мелкий вопрос — какое время указывать у глаголов? Если указывать везде одно и то же время, неважно — настоящее это, прошедшее или будущее, то разработчик может не отличить последовательность действий.
Например — «Пользователь достаточным кредитом добавляет продукт в корзину и указывает количество. Зарезервированное количество продуктов на складе увеличивается».
Добавление и указывания количества — это разные операции или одна? А резервация продуктов связана с кредитом, или она для всех типов пользователей происходит?
Необходимо использовать разное время, либо более формально отделять precondition, user action, system reaction и post-condition.
Средства
Я визуал и предпочитаю изображения — UML диаграммы, эскизы (balzamiq, axure), скриншоты со стрелками. Когда дело касается рутинных функций, без текста и списков не обойтись. Таблички полезны когда списки не работают — взаимозависимых данных становится много и они многомерны.
Когда я пытался разобраться в существующих требованиях и существующем проекте, то очень помогал Mind Map, группируя и связывая задачи и требования, создавая точки фокуса. Готовое решение для повторно используемого UI-компонента часто хочется показать разработчикам. Без кода с подсветкой тоже никуда.
Был опыт видеозаписи участка экрана для багов, что-бы показать анимацию и поведение существующего решения. Но для документирования quicktime тоже применим.
Автоматические тесты, да и мануальные формализованные тексты в TestRail, заготовки для UI тестов, наброски BDD — всё это тоже средства документации и проверки решения.
Автогенераторы документации и диаграмм полезны для создания документации по решению — mysql workbench, phpdoc, doxygen, jsduck. Это из разряда холиваров, когда стоит писать тесты — до кода или после него.
Для агрегации всей документации я в основном использовал Confluence, но можно посмотреть на MediaWiki или Google docs. Недостаток их всех в оторванности от кода и git-repo. Хранить документацию вместе с кодом лучше в формате markdown. Редакторы — Mou, Atom, IntelliJ, Marked, Visual Studio Code.
См также:
- Painless Functional Specs
- On Writing Product Specs
- How to write a product vision
- Specifying good requirements
Наконец, вот шаблон для спеки. Оставьте только стоящие упоминания пункты!
1. Концепция / Обзор
О чём речь?
- Проблема и цели
- Stakeholders — заинтересованные пользователи. Кого это касается?
- Отделы компании — кого затронут изменения, кто что должен будет сделать в процессе
- Типы пользователей — visitor, user, client, admin
- Предположения (assumptions) — пользователи, доступность технологий, экономические факторы, развитие конкурентов, вероятное качество данных поставщиков
- Ограничения (constraints) — независящие от всех обстоятельства по времени, законодательству
- Scope — что по функционалу войдёт, а что нет
- Timeline/Lifecycle — что будет происходить после релиза, как будет меняться продукт/этот функционал впоследствии по времени
Скриншот самой важной области
2. Требования
Что мы хотим получить? Общие требования с точки зрения пользователя, не предлагая конкретного решения. Разделив требования от решения подход становится более формализованным и тестируемым.
Цели для каждой из заинтересованных групп.
- Бизнес-требования. Что необходимо компании? Увеличить прибыль, ускорить рост, снизить риски
- Пользовательские. Что необходимо конечному пользователю? Ускорение UI, облегчение действий, новые функции.
- Технические. Что необходимо разработчикам? Поддержка кода, масштабируемость инфраструктуры, определение ошибок.
Из личного опыта, вовремя спросив «зачем бизнесу нужен отдельная от приложения форма авторизации», мы значительно сэкономили время на реализации кросс-доменной авторизации, которая на самом деле бизнесу не нужна была и остались на том же домене, просто с другим дизайном
В больших компаниях, каждое требования выписывается в отдельную БД и получают уникальный ID, на который ссылаются UI-мокапы, код и тесты. Примерно как ticket ID в Jira. Инструменты — SPEQit, Accompa
2.1 Нефункциональные требования
Каким мы хотим получить продукт?
Нефункциональные требования при работе продукта
- Performance — максимальное количество одновременных пользователей, есть ли разница в зависимости от разных операций (read/write/delete), максимальная пропускная способность, время вычисления, время ответа и реакции, загрузка CPU, IO, памяти, max filesize
- Reliability — как обрабатываются ошибки, перезапуск, дублируются ли данные, failsafe режимы, транзакции
- Security — разграничение ролей пользователей, какая снижаются риски атак, как хранятся личные данные
- Usability — ограничения по удобству, минимальное количество кликов при операциях, скорость обновления интерфейса, скорость загрузки страниц, количество элементов в формах или скорость заполнения среднестатистическим пользователем. Есть ли style guide
- Configurability — где лежат настройки, централизованы ли они, используют ли какой-то сервис
- Availability — сколько сервис максимально может быть в дауне
- Durability — сколько надо хранить данные/логи после использования
- Scalability — есть ли вертикальное/горизонтальное масштабирование сервиса или он фиксирован
Нефункциональные требования при создании
- Reusability — можно ли повторно использовать, надо ли что-то при этом менять
- Extensibility — можно ли расширить, добавив новые функции
- Portability — можно ли запустить на других платформах
- Interoperability — можно ли компонент использовать согласно открытому стандарту / протоколу
- Supportability — простота в поддержке. Как легко понять логи, обнаружить ошибку, восстановить данные. Как предсказуемо поведение. Сколько стоит поддержка, какие требования по стилю и качеству кода, техническому долгу
- Modularity — разделён ли функционал на части и почему. Как при этом происходит сборка и движутся данные
- Testability — какие типы тестов должны быть и что покрывать, насколько код и архитектура должны быть тестируемыми
- Localization — надо ли что-то переводить на другой язык, есть ли различие по странам, насколько сложные могут быть фразы, как легко можно добавлять переводы
- Compatibility — совместимость с разными устройствами и браузерами. Надо ли поддерживать старые версии приложения
- Legal — ограничения на использование лицензий, влияние на privacy policy, client agreement
- Accessibility — надо ли поддерживать пользователей с ограничениями зрения. Hotkeys, поддержка разных устройств ввода, SEO-оптимизация
2.2 Функциональные требования
Что мы хотим получить в продукте?
- Пользовательские сценарии / Use cases (краткий обзор, детальней в решении)
- Для компонентов — размеры, события, анимация, позиционирование, связи с другими элементами (z-index)
- Business rules — какие ограничения накладывает прикладная область, государственные регуляторы, международные стандарты, контракты
2.3 Риски и сложности
Что надо учитывать, какие взаимосвязи со всем проектом
- Варьирующиеся и неопределённые внешние требования, сроки и требования по качеству
- Внутренние требования (мониторинг, логи, транзакции)
- Технические зависимости (легаси, тех. долг)
- Неизвестность инструментов и технологий, предметной области
- Человеческие зависимости
- Человеческие отношения — доверие менеджмента комманде, комманды менеджменту (партизанинг), увольнения
- Структура компании, межкоммандное взаимодействие, субподрядчики, партнёры
- Внутриполитические дрязги, политика
Нынешнее состояние. Как будет происходить изменение продукта технически и организационно. Кто за что отвечает
Худшие последствия
Как сильно компания чувствительна к провалу этого проекта?
Какие могут быть репутационные потери, потеря и повреждение данных, юридические обязанности поддерживать решение?
3. Техническое решение
Как это будет сделано? Преимущества и недостатки
Терминология
Единый словарь должен использоваться не только клиентом но и в css, в коде, в базе
Вид статических данных
Терминология плавно перетекает в связи между сущностями:
- Entity Relationship диаграмма включает связи сущностей (1:n, n:m).
- Нормальная схема БД. Включает, свойства и их типы, внешние ключи
- Class диаграмма — описывают какие классы в коде будут связаны с какими данными. Начинается описание поведения (методов)
Все эти диаграммы говорят о гибкости (насколько сущности разделены), понимаемости (названиях), тестопригодности (инкапсуляции) приложения
Вид пользователя
Пользовательские сценарии (use-case диаграмма) — пошаговое описание функций (роль пользователя, причина, действия, последствия)
Альтернативные сценарии (ошибки, валидация ввода). Что должно происходить с частично обработанными данными при ошибках?
Визуальный дизайн
- Навигация (URL, меню, граф взаимосвязей видов)
- Эскизы / наброски UI (mockup на доске, бумаге)
- Визуальный дизайн интерфейса (PSD / HTML) — стиль, анимации, бренд, цвета, шрифты, вдохновение
- Динамический дизайн / HMTL + JS. Очень полезен для frontend компонентов. Анимация, взаимодействие.
Вид динамических данных
Поток данных (data flow) — архитектурный обзор как данные кочуют между сервисами, что от чего зависит
Диаграмма взаимосвязей API
Взаимодействие (collaboration) — какие компоненты кого вызывают по каким методам
Последовательность (sequence) — в каком порядке идёт обмен данными между объектами во времени для конкретной операции
Конечный автомат (state machine) — в каких состояниях данные бывают
Вид сервера
- Технологии и инструменты для сборки
- Новые зависимости
- Библиотеки и фреймворки
- Репозитории
- Использование внешних API
- Отдача своего API вовне
- Конфигурация
- Серверы
- Исключения, коды ошибок
- Rest API — Swagger, Apiary
- Background-задачи (cron, MQ очереди)
- Код для повторного использования компонента
- Какое железо, серверы участвуют, какие компоненты на каких серверах живут
- Какие шаги по релизу. Миграции БД, сервера. Как происходит откат неудачного релиза, бэкап