```json
{
    "title": "Функциональная архитектура цифровых продуктов, часть 5",
    "url": "https://sherer.pro/blog/funkcionalnaya-arhitektura-cifrovyh-produktov-chast-5/",
    "datePublished": "2025-02-17",
    "dateModified": "2026-07-27",
    "language": "ru-RU",
    "description": "Детальное функциональное проектирование и частые, но не всегда очевидные подводные камни.",
    "author": "Павел Шерер",
    "publisher": "Павел Шерер"
}
```

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

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

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

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

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

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

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

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

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

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

- **Глаголы**: название функции, как правило, должно отражать действие. Например, из названия `AddUser` сразу понятно, что происходит добавление пользователя.
- **Минимум аббревиатур**: если аббревиатура не общеизвестна, лучше её избежать. Если же совсем никак, заведите в проектной документации [словарь](https://sherer.pro/blog/uchim-proektnuju-komandu-chitat/#3-6-slovar-terminov).
- **Ясность**: человек должен понимать суть функции, даже если читает её название впервые.

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

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

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

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

![Функциональная схема регистрации пользователя](https://sherer.pro/content/uploads/2024/11/functional-arch-registration-scaled-1.jpg)

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

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

![Функциональная схема подтверждения e-mail](https://sherer.pro/content/uploads/2024/11/functional-arch-confirm-email-scaled-1.jpg)

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

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

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

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

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

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

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

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

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

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

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

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

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

### Названия экранов

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

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

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

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

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

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

## Подводные камни

Как и везде, при работе над функциональной архитектурой, можно порядком наломать дров. Очень не хочется, чтобы ФА постигла [участь](https://sherer.pro/blog/personazhi-po-kuperu-kak-diskreditirovat-metodologiyu/) куперовских персон.

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

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

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

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

Пример:

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

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

Я часто об этом говорю (например, [здесь](https://sherer.pro/blog/funkcionalnaja-arhitektura-cifrovyh-produktov-chast-2/?highlight=%D0%B0%D0%B1%D1%81%D1%82%D1%80%D0%B0%D0%BA%D1%86%D0%B8%D0%B8#3-1-uroven-abstrakcii)), и повторю снова.

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

Пример:

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

### Технические знания

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

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

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

Пример:

При проработке внутренней части корпоративного блога, дизайнеры и аналитики не продумали возможность взаимной блокировки редактора (это когда ты не можешь править текст, который правит кто-то другой). Разработчики тоже не додумались. В итоге какое-то время, пока не внедрили [веб-сокеты](https://developer.mozilla.org/ru/docs/Web/API/WebSockets_API), контент-менеджеры перезатирали изменения друг друга.

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

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

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

Пример:

Делали мобильное приложение. Одной из метрик эффективности продуктового дизайна была конверсия. Однако для пользователей из разных каналов необходимо было создать уникальный опыт. Пришёл с YouTube — один сценарий, с Telegram — другой. Дизайнеры тупо добавили на начальный экран вопрос "откуда вы пришли". Хотя достаточно было сходить к маркетологам или разрабам, чтобы они рассказали про такое чудо инженерной мысли, как [диплинки](https://habr.com/ru/companies/otus/articles/688728/).

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

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

Один мой клиент (Алексей, привет) нашёл прекрасную аналогию: [нулевой цикл строительства](https://vector-shpunt.ru/blog/raboty-nulevogo-tsikla-stroitelstva/). Это когда в здание уже влито много-много денег, но ни одного этажа ещё не построено. Проведены геологические исследования, получены все разрешающие документы, подведены коммуникации — но внешне всё остаётся практически таким же, как было в самом начале.

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

Антипример:

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

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

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

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

Пример:

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

## Итог

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

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