Функциональная архитектура цифровых продуктов, часть 5

Детальное функциональное проектирование и частые, но не всегда очевидные подводные камни.

7-9 минут на прочтение
Функциональная архитектура цифровых продуктов, часть 5

Это — последняя часть цикла про функциональное проектирование. Здесь мы поговорим о детальном функциональном проектировании и разберём несколько подводных камней.

В целом, этого цикла должно быть достаточно, чтобы вы уверенно начали работать с функциональной архитектурой, не опасаясь заблудиться в нюансах.

1. Детальное функциональное проектирование

Как вы помните, в предыдущих статьях я различал высокоуровневое и детальное проектирование. И если о первом уже говорилось достаточно, то пришло время поглубже рассмотреть второе.

1.1. Именование функций

У каждой функции и каждого функционального раздела должно быть своё уникальное название. Названия должны быть максимально понятными и самодостаточными. Используйте английский язык — это обеспечит единое понимание в команде (особенно если она международная) и немного упростит работу программистов.

Удачное название функции упрощает её поддержку и снижает риск двусмысленности.

Примеры удачных названийПримеры неудачных названийПричина «неудачности»
UserRegistrationReg – Слишком краткое и абстрактное название, которое неясно передаёт смысл функции.
– Аббревиатура «Reg» может быть интерпретирована по-разному (например, «регистрация», «регион» или даже «регламент»).
AddToCartAddItem – Название «AddItem» не указывает на конкретное место назначения – куда именно добавляется элемент.
– В контексте онлайн-магазина важно подчеркнуть, что речь идёт о корзине (cart), а слово «Item» само по себе может использоваться в различных сценариях, не только в e-commerce.
SubmitReportReportSubmission – Использование существительного вместо глагола может сделать название менее динамичным и не столь интуитивно понятным.
– «SubmitReport» сразу сигнализирует о действии – отправке отчёта, тогда как «ReportSubmission» звучит как описание процесса или объекта, а не как команда для выполнения функции.
VerifyEmailEmailCheck– Название «EmailCheck» менее конкретно. Оно не уточняет, что именно проверяет функция: корректность или подлинность email-адреса.
– Глагол «Verify» в «VerifyEmail» чётко указывает на необходимость верификации (проверки) адреса, что более точно отражает суть задачи, в то время как «Check» может трактоваться как поверхностная проверка без гарантии достоверности.

Неудачные названия часто бывают слишком абстрактными или краткими, что затрудняет чтение и может привести к ошибкам при оценке и реализации. Следуйте нескольким простым правилам:

  • Глаголы: название функции, как правило, должно отражать действие. Например, из названия AddUser сразу понятно, что происходит добавление пользователя.
  • Минимум аббревиатур: если аббревиатура не общеизвестна, лучше её избежать. Если же совсем никак, заведите в проектной документации словарь.
  • Ясность: человек должен понимать суть функции, даже если читает её название впервые.

1.2. Функциональные сценарии

Функциональные сценарии прорабатываются итеративно: от самых простых к детализированным. К этому времени накапливается достаточное количество данных для их глубокой проработки.

Пример высокоуровневого сценария для UserRegistration:

  1. Пользователь открывает страницу регистрации.
  2. Вводит свои данные.
  3. Нажимает кнопку «Зарегистрироваться».
  4. Валидация: система проверяет данные.
    • Если всё корректно, создаётся аккаунт, и на почту отправляется письмо для подтверждения.
    • Если данные некорректны, отображается ошибка.
  5. Подтверждение: пользователь переходит по ссылке в письме, чтобы подтвердить регистрацию.
  6. Если почта не подтверждена в течение 24 часов, аккаунт удаляется, пользователю показывается сообщение об ошибке.

Теперь рассмотрим, как можно детализировать отдельный фрагмент такого сценария: например, ConfirmEmail:

  • Мы проработаем обмен данными и их сохранение.
  • Для каждой проверки будет выделена отдельная функция.

Обратите внимание, что над некоторыми клиентскими функциями указаны названия и состояния экранов (например, ConfirmEmail.check) — мы к этому ещё вернёмся.

1.3. Описание функций

Однако одних сценариев зачастую оказывается не достаточно. Передать абсолютно всю информацию о функции и её работе с помощью схем не всегда возможно. С этой задачей вообще слабо справляются любые графические средства, хоть ФС, хоть диаграммы последовательностей. Да, разного рода схемы позволяют однозначно определить сценарии и потоки данных, но какие-то вещи можно отобразить только в виде текста.

Описание функции должно быть лаконичным и понятным для всех участников команды: от разработчиков до уборщиков и бизнес-специалистов. Что обычно включает в себя описание функции:

  • Назначение: зачем нужна функция и что она делает.
  • Входные и выходные данные: какие данные функция принимает и что возвращает (если применимо).
  • Зависимости: с чем функция взаимодействует, без чего не будет работать (например, функциональный раздел confirmPhone не получится реализовать до того, как будет готов sendSMS).
  • Пример использования: когда и как функция применяется.

Пример упрощённого описания функции AddToCart:

  • Назначение: добавить товар в корзину для оформления заказа.
  • Входные данные: идентификатор sku и количество count товаров, идентификатор пользователя guid.
  • Выходные данные: обновлённое состояние корзины, массив cardState.
  • Зависимости: InventoryService (для проверки наличия товара).
  • Пример использования: пользователь добавляет товар в корзину, система проверяет наличие и обновляет состояние корзины.

Здесь можно добавить User Stories, Use Cases и вообще всё, что вы посчитаете нужным. Главное, чтобы описание было трактуемым однозначно.

Итеративная работа над сценариями позволяет их улучшать по мере получения новой информации и обратной связи от связанных специалистов или пользователей.

2. Названия и состояния экранов

Практически каждая функция системы так или иначе связана с каким-либо экраном. Кажется очевидным, что экраны и функции нужно прорабатывать совместно, однако я часто встречал ситуации, когда дизайнеры работают независимо от аналитиков и разработчиков.

Проработка экранов и их состояний не может быть отделена от функционального проектирования.

Вспомните, сколько раз вы получали (или предоставляли) макеты, где нет «нулевых» состояний или не предусмотрены «пограничные» ситуации, вроде ошибки загрузки данных.

2.1. Названия экранов

Название экрана должно ясно объяснять его назначение. Если у вас в Figma экраны будут именованы так же, как в проектной документации, это упростит работу фронтендеров и сделает эту документацию более консистентной.

Название экранаОписание
RegistrationЭкран для регистрации новых пользователей.
ShoppingCartЭкран, на котором отображаются добавленные товары.
OrderConfirmationЭкран подтверждения деталей заказа перед покупкой.

2.2. Состояния экранов

Каждый экран может находиться в различных состояниях, которые важно предусмотреть заранее. Пример состояний для экрана ShoppingCart:

Экран и состояниеОписание
ShoppingCart.defaultЗагруженное состояние. Отображаются товары, их количество и цена; пользователь может изменить количество или удалить товар.
ShoppingCart.emptyПустое состояние. Нет товаров в корзине; выводится сообщение: «Ваша корзина пуста. Начните покупки прямо сейчас!»
ShoppingCart.errorСостояние ошибки. Отображается сообщение об ошибке и предложение повторить попытку позже или обратиться в поддержку.

Помните, в сценарии над некоторыми клиентскими функциями указывались названия и состояния экранов? А теперь представьте, что это — ссылки на конкретные фреймы в Figma. Разработчикам не нужно больше играть в «найди 10 различий», они видят взаимосвязь функций и экранов напрямую.

3. Подводные камни

Как и везде, при работе над функциональной архитектурой, можно порядком наломать дров. Очень не хочется, чтобы ФА постигла участь куперовских персон.

Ниже я перечислил самые частные ошибки и недоработки, которые допускал сам или видел у других.

3.1. Недостаточная проработка

Иногда хочется приступить к разработке пораньше. Это желание понятно, я много раз слышал обвинения в «вотерфольности» моего подхода. И именно «аджайлами» люди частенько прикрывают нежелание или неумение нормально проектировать. Ну что ж, дело хозяйское.

Я хочу только отметить, что недостаточная глубина проработки архитектуры создаёт ложное ощущение безопасности. Проблемы проявляются позже, когда проект уже зашёл слишком далеко, и исправления становятся всё более дорогими и трудоёмкими. Действуйте итерациями, никто не предлагает сначала продумать всё, и только потом садиться разрабатывать.

Пример:

Как-то я участвовал в доработке внутреннего портала одной компании под нужды другой (частый кейс). Руководство надавило, и в разработку была отдана сырая архитектура. Позже выяснилось, что спроектированная система не полностью поддерживает необходимое согласование отпусков и расчёт налогов. Масштабная переработка, срок сдачи сдвинулся на полтора месяца.

3.2. Уровень абстракции

Я часто об этом говорю (например, здесь), и повторю снова.

Правильный уровень абстракции — это баланс. Слишком высокий абстрагирует архитектуру от реальности, а слишком низкий перегружает деталями, усложняя восприятие и развитие.

Пример:

В одном из недавних проектов аналитик проявил чудеса самостоятельности и (пока никто не видел) расписал в деталях одну из подсистем. Но его работа не учитывала огромное количество нюансов других компонентов, которые к тому времени ещё не были спроектированы. Итог: вся работа в мусорку.

3.3. Технические знания

Казалось бы, странно требовать от дизайнеров каких-либо знаний в технических областях. Но нет, не странно.

Невозможно задизайнить сложную систему, не понимая, как она будет работать

Недостаток технических знаний у дизайнеров, архитекторов или аналитиков приводит к принятию необоснованных решений. Либо наоборот, авторам архитектуры даже не приходит в голову, что существуют технологии, способные существенно упростить пользовательский опыт.

Пример:

При проработке внутренней части корпоративного блога, дизайнеры и аналитики не продумали возможность взаимной блокировки редактора (это когда ты не можешь править текст, который правит кто-то другой). Разработчики тоже не додумались. В итоге какое-то время, пока не внедрили веб-сокеты, контент-менеджеры перезатирали изменения друг друга.

3.4. Консультации с экспертами

Этот «камень» логически проистекает из предыдущего. Невозможно знать всё. Но можно не стесняться подключать к проектированию специалистов смежных областей. И речь тут не только про технологии, но и про них тоже.

Чем раньше вы «обстучите» свои решения об ваших коллег, тем более надёжными они станут. Игнорирование консультаций с экспертами приводит к критическим проблемам на поздних стадиях проектирования, разработки и внедрения. Привлечение специалистов позволяет выявить уязвимости проектирования в целом и функциональной архитектуры в частности ещё до начала разработки.

Пример:

Делали мобильное приложение. Одной из метрик эффективности продуктового дизайна была конверсия. Однако для пользователей из разных каналов необходимо было создать уникальный опыт. Пришёл с YouTube — один сценарий, с Telegram — другой. Дизайнеры тупо добавили на начальный экран вопрос «откуда вы пришли». Хотя достаточно было сходить к маркетологам или разрабам, чтобы они рассказали про такое чудо инженерной мысли, как диплинки.

3.5. Донесение ценности до бизнеса

Самый больной «камень». Хотя он и не подводный вовсе, а очень даже надводный. Знали бы вы, сколько раз мне приходилось доказывать клиентам, что начинать разработку ещё слишком рано. Или что влитые в проектирование деньги сохранят бюджет проекта в дальнейшем.

Один мой клиент (Алексей, привет) нашёл прекрасную аналогию: нулевой цикл строительства. Это когда в здание уже влито много-много денег, но ни одного этажа ещё не построено. Проведены геологические исследования, получены все разрешающие документы, подведены коммуникации — но внешне всё остаётся практически таким же, как было в самом начале.

Если бизнес не понимает ценность архитектурных решений, проект не получит достаточной поддержки. Важно доносить ценность функционального проектирования до всех заинтересованных сторон.

Антипример:

Я смог донести до клиента важность проектирования и исследований. Сам ездил со специалистами, прикидываясь стажёром. Выкопали вообще все бизнес-процессы до самых корней. С момента начала проектирования до первой строчки кода прошло 9 месяцев. Зато релиз вышел почти через год после начала разработки. Итог: от первой встречи с клиентом до релиза — один год и 11 месяцев. Ключевой конкурент потратил на это почти 5 лет с командой, в 3 раза больше нашей.

3.6. Лень и возврат к общей картине

Как я уже говорил, продумать всё невозможно. Да, вы были хороши и ваша высокоуровневая архитектура прекраснее, чем «Битва кентавров» Микеланджело. Но будьте готовы, что в процессе детальных изысканий вам придётся возвращаться на высокий уровень. И не просто возвращаться, а кое-где существенно его изменять.

Увлечение деталями иногда мешает вернуться к общей концепции. Это ведёт к потере видения конечной цели и необходимости исправлений.

Пример:

Я проектировал одного из своих питомцев. Вроде, предусмотрел всё, всю свою маркерную доску испещрил сценариями, был готов приступать к разработке. Осталось совсем немного: добить механики копирования пункта в собственный вишлист. А это повлекло за собой пересмотр механик регистрации (потому что теперь это нужно было делать не с отдельной страницы) и механик создания вишлиста (по той же причине). Пришлось возвращаться на высокоуровневое проектирование и изменять структуру API. Хорошо, код писать не начал, переписывал бы.

4. Итог

Если вы дочитали эту статью до конца, значит, у вас достаточно мотивации, чтобы начать (или продолжить) делать правильно. Если же вы просто проскроллили вниз — мои соболезнования (и ноль процентов осуждения). Всё, что я мог сделать, чтобы стабилизировать процесс проектирования и разработки, я в этом цикле сделал.

Дальше дело за вами.

Павел Шерер, продюсер IT-решений

Канал в Telegram

Раньше тут были комментарии, но я решил не плодить сущности. Есть что сказать или спросить — велкам в телеграм-канал:

Обсудить в Telegram