Эта статья прежде всего будет полезна студентам и начинающим специалистам.

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

В первой статье по этой теме https://habr.com/ru/articles/1054184/ я рассказывал про принципы декомпозиции программной системы на модули и слои программных компонентов на примере задачи разработки бэкенда корпоративных чатов, рассмотрел пример реализации модуля идентификации и аутентификации пользователей на языке программирования Go.

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

Процесс разработки программного обеспечения

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

Обычно сбор требований начинается с довольно неясного желания заказчика. Например, нужно разработать систему для корпоративных чатов. Прежде чем разрабатывать такое ПО команда разработки должна выяснить требования. Что конкретно должна уметь делать система, какие возможности для пользователей она должна предоставлять, какими характеристиками она должна обладать?

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

Требования принято делить на функциональные и нефункциональные.
Функциональные требования описывают, что должна делать система. 
Нефункциональные требования определяют, как система должна работать.

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

Производительность: задержка между отправкой сообщения и доставкой его адресату должна быть не более 3 сек.  

Масштабируемость: система должна выдерживать нагрузку до 10 тыс одновременных пользователей без снижения скорости отклика.

Совместимость: Продукт должен корректно работать в последних версиях браузеров на компьютерах и мобильных устройствах.

Надежность и доступность: Время бесперебойной работы (аптайм) должно составлять не менее 99,9% в режиме 24/7.

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

Пользовательская история описывает некоторую возможность системы с позиции пользователя. Например так.

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

Таким образом, история - это описание некоторой возможности, фичи (от англ. feature - особенность, отличительная черта). Истории формируются так, чтобы реализовать требования.

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

Можно выделить такие задачи по разработке бэкенда для реализации истории:

  • Регистрация пользователя в системе (создание пользователя, создание и отправка кода подтверждения)

  • Логин пользователя (проверка существования пользователя, создание и отправка кода подтверждения)

  • Аутентификация пользователя (проверка кода подтверждения и создание новой сессии)

  • Логаут пользователя (удаление сессии)

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

После разработки задачи поступают на тестирование к отдельным специалистам по контролю качества, их называют QA-инженерами или тестировщиками.

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

Отдельным путем обычно идут исправления ошибок в системах, которые уже внедрены и используются. По хорошему для баг-фиксов нужно заводить истории, но часто обходятся отдельными задачами, если ошибка локализована в одном модуле. Задачи и истории для исправления ошибок группируют в патчи и публикуют их чаще релизов, обычно раз в неделю.

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

Процесс разработки требований и инструменты визуализации

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

Бизнес-процесс - это упорядоченный набор связанных между собой действий, которые выполняются участниками (людьми или программами) для превращения исходных данных в полезный результат. У каждого процесса есть цель, участники, начало, конец, порядок и правила взаимодействия между участниками.

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

Вместе с требованиями часто употребляется понятие “техническое задание”, но это немного другое. Обычно техническое задание - это документ, описывающий как именно будет реализован проект, отвечающий требованиям, включая критерии приемки, этапы, подробности реализации и сроки. Обычно техническое задание появляется после сбора и согласования требований.

При обсуждении бизнес процессов и уточнении требований очень помогают различные средства формального описания и формальной визуализации бизнес-процессов. Для описания бизнес-процессов часто применяют BPMN - Business Process Model and Notation - международный стандарт графического описания бизнес-процессов. BPMN-схемы похожи на блок-схемы алгоритмов. Основное отличие такое: BPMN-схема - это сквозная схема общего алгоритма всего бизнес-процесса, объединяющая алгоритмы функционирования отдельных компонентов и схему их взаимодействия.   

BPMN (Business Process Model and Notation)

В качестве примера приведу примитивную BPMN-схему для процесса общения в корпоративном чате. Но вначале дам текстовое описание бизнес-процесса.

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

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

Примитивная BPMN-схема описанного процесса выглядит примерно так.

BPMN-схема процесса общения в корпоративном чате
BPMN-схема процесса общения в корпоративном чате

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

Что происходит на схеме, приведенной выше?

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

Следующий подпроцесс - собственно общения для пользователя в роли участника чата. Общение может начинаться с уведомления о приглашении в чат или пользователь открывает приложение в новом окне/вкладке или приложение уже открыто. В любом список чатов загружается впервые или периодически перезагружается с сервера - это скорее всего один и тот же запрос к серверу.

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

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

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

Данная схема помогает понять что основными операциями модуля чатов в первой версии приложения будут:

  • Создание нового группового чата

  • Добавление нового участника в чат

  • Загрузка списка чатов, в которых состоит пользователь

  • Загрузка сообщений чата

  • Отправка нового сообщения в чат, в том числе с привязкой к другому сообщению, ответом на которое является наше новое сообщение

Реализация бизнес процесса приводит к разработке программного продукта, которых состоит из частей - подсистем, сервисов, отдельных программ, модулей, разрабатываемого программного кода и используемых готовых частей - СУБД, программных библиотек функций/классов, вспомогательных программ, интеграций с другими системами. Все это можно визуализировать с помощью структурных схем. Для этого часто применяют нотацию С4.

C4 (Context, Containers, Components, Code)

Нотация C4 получила название по 4 основным абстракциями, с которыми она работает - сontext, сontainers, сomponents, сode. Нотация C4 помогает визуализировать декомпозицию системы на составные части на разных уровнях анализа и обсуждения.

Уровень контекста показывает как разрабатываемая программная система взаимодействует с внешними сущностями - пользователями и другими системами. На этом уровне удобно показывать интеграции с внешними системами.

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

Пример схемы контекста
Пример схемы контекста

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

Пример схемы контейнеров
Пример схемы контейнеров

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

Пример схемы компонентов
Пример схемы компонентов

На уровне кода можно показать детали реализации компонентов. Схему этого уровня есть смысл рисовать если предполагается сложная неочевидная внутренняя программная архитектура, что-то нетипичное.

Подведем итоги

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

Для визуализации структуры систем стала популярна нотация C4 (сontext, сontainers, сomponents, сode). Она позволяет постепенно углубляться в структуру компонентов системы, начиная с самого высокого уровня, где система представляется одним блоком и показываются интеграции разрабатываемой системы с другими системами. Затем можно постепенно детализировать структуру, заканчивая схемой взаимодействия между абстракциями и компонентами исходного кода программ системы.

Для визуализации желаемого функционирования систем часто применяют схемы бизнес-процессов в нотации BPMN. Этот подход удобен тем, что объединяет алгоритмы функционирования компонентов системы в единый процесс. В принципе то же самое раньше изображали в виде блок-схем алгоритмов. Но с тех пор как системы стали распределенными, взаимодействующими через сеть, блок-схемы отдельных алгоритмов отдельных компонентов системы стали недостаточно наглядными.

Иными словами, если хотим изобразить структуру - компоненты и их взаимосвязи - используем C4. А когда хотим изобразить логику функционирования компонентов системы - используем BPMN-схемы бизнес-процессов.

Благодарю, что дочитали до конца. Надеюсь, эта статья была полезна для вас.