Материал учебного циклаОткрытый материал

UML: как описывать программную систему с разных сторон

Введение в UML и основные виды диаграмм. Разбираем, зачем одной системе нужны разные представления, что показывают Use Case, Sequence, Class, Activity, State Machine, Component и Deployment Diagram и как выбрать подходящую диаграмму под задачу.

Продукт и интерфейсы #UML
Учебный цикл Моделирование и проектирование информационных систем Материал 2 из 9

UML простыми словами: зачем одной системе несколько диаграмм

UML(Unified Modeling Language) - Унифицированный язык моделирования. Это не одна диаграмма, а набор способов посмотреть на программную систему с разных сторон.

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

Упрощённо:

Use Case - кто и зачем взаимодействует с системой
Sequence - кто кого вызывает и в каком порядке
Class - какие сущности и отношения существуют в коде
State Machine - как объект меняет состояние
Component - из каких программных блоков состоит система
Deployment - где эти блоки физически запускаются

Главная идея UML в том, что одну систему нельзя одинаково хорошо описать одной схемой.

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

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

Use Case Diagram

Use Case Diagram показывает, кто взаимодействует с системой и какие возможности система ему предоставляет.

Основные элементы:

  • Actor;
  • Use Case;
  • System Boundary;
  • Include;
  • Extend;
  • Generalization.

Actor - участник, который взаимодействует с системой.

Например:

Абитуриент - подать заявку
Оператор - проверить заявку
Администратор - настроить программу

Actor не обязательно является конкретным человеком. Это роль по отношению к системе.

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

Use Case описывает цель пользователя или внешней системы.

Например:

Подать заявку
Проверить заявку
Сформировать отчёт
Настроить программу

Use Case не должен подробно описывать внутренний алгоритм выполнения операции.

То есть диаграмма отвечает на вопрос:

Что пользователь может сделать с системой?

а не:

Какие методы Python будут вызваны внутри backend?

System Boundary показывает границу рассматриваемой системы и помогает отделить её возможности от внешних участников.

Связи include и extend позволяют показать отношения между сценариями.

include используется, когда один сценарий обязательно включает другой.

extend позволяет показать дополнительное поведение, возникающее только при определённых условиях.

Use Case Diagram особенно полезна на раннем этапе проектирования, когда нужно понять границы системы и основные пользовательские возможности.

Sequence Diagram

Sequence Diagram показывает, как участники и компоненты взаимодействуют друг с другом во времени.

Например, создание заявки может выглядеть так:

React -> POST /applications -> Django -> PostgreSQL -> RabbitMQ -> Celery

На диаграмме обычно используются:

  • Lifeline;
  • Message;
  • Return;
  • Activation;
  • Synchronous Call;
  • Asynchronous Message;
  • alt;
  • opt;
  • loop.

Lifeline показывает участника взаимодействия.

Это может быть:

User
Frontend
Backend
Database
Message Broker
External API

Messages показывают взаимодействия между ними.

Например:

React -> Django: POST /applications
Django -> PostgreSQL: INSERT application
Django -> RabbitMQ: publish notification task
RabbitMQ -> Celery: deliver task
Django -> React: 201 Created

Activation показывает блоки активности

Synchronous Call показывает синхронный вызов

Return показывает возврат управления

Например:

PostgreSQL --> Django

Asynchronous Message показывает асинхронное сообщение.

Например:

Бэкенд не ждет пока Celery завершит работу, 
а сразу возвращает ответ пользователю

Sequence Diagram особенно полезна для backend-разработки и интеграций, потому что позволяет увидеть порядок вызовов и границы ответственности между компонентами.

Она также хорошо показывает альтернативные сценарии.

Например:

alt заявка валидна -> сохранить данные
else заявка невалидна -> вернуть ошибку

opt используется для необязательного сценария, а loop - для повторяющихся действий.

Если Use Case отвечает на вопрос что пользователь может сделать, то Sequence Diagram показывает как конкретный сценарий проходит через систему.

Class Diagram

Class Diagram описывает структуру классов программной системы.

Она позволяет показать:

  • Class;
  • Attribute;
  • Method;
  • Association;
  • Aggregation;
  • Composition;
  • Inheritance;
  • Multiplicity.

Простейший класс может содержать имя, поля и методы.

Например:

Application

id
status
created_at

submit()
approve()
reject()

Class Diagram позволяет показать отношения между объектами.

Например:

User -> Application
Application -> Document
Application -> Program

Attribute - характеристика объекта и её тип. Запись status: ApplicationStatus говорит, какие значения может хранить статус.

Association показывает устойчивую связь между объектами. Например, пользователь подаёт заявку, а заявка относится к программе. Простая линия ещё не означает ни владения, ни удаления одного объекта вместе с другим. У концов линии можно подписать роли и кратность.

В зависимости от отношения могут использоваться association, aggregation, composition или inheritance.

Aggregation обозначает отношение целого и части со слабым владением. Его рисуют линией с незакрашенным ромбом у целого. Например, учебная программа может объединять курсы, существующие и независимо от неё. Использовать aggregation для любой связи «содержит» не стоит: если особого смысла владения нет, обычная association понятнее.

Composition обозначает более сильное владение и рисуется с закрашенным ромбом у целого. Если документ рассматривается как часть конкретной заявки и в этой модели не может одновременно принадлежать другой заявке, связь Application с ApplicationDocument можно показать композицией. Это утверждение о жизненном цикле объектов модели, а не автоматическое требование удалить строку базы данных каскадным SQL-запросом.

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

Multiplicity показывает количество связанных объектов.

Например:

Program 1 -> * Application

Одна программа может содержать множество заявок.

Важно не путать Class Diagram и ERD.

UML Class Diagram - программная модель
ERD - модель данных в базе

Они действительно могут выглядеть похоже.

Например, и там и там можно увидеть:

User
Application
Document

Но смысл разный.

ERD отвечает на вопросы о таблицах, ключах и связях данных.

Class Diagram показывает структуру объектов программы, их поведение и отношения.

Activity Diagram

Activity Diagram используется для описания последовательности действий.

Основные элементы:

  • Action;
  • Decision;
  • Merge;
  • Fork;
  • Join;
  • Start;
  • End.

Простой процесс можно представить так:

Получить заявку -> Проверить данные -> Данные корректны? -> Согласовать заявку -> Завершить

Когда дальнейший путь зависит от условия, используют Decision Node

При этом появляются развилки:

Данные корректны? -> Да -> Согласовать
Данные корректны? -> Нет -> Вернуть на исправление

Guards говорит об условиях Actions процесса

Fork и Join позволяют показать параллельные действия.

Например:

Заявка согласована -> одновременно создать пользователя + отправить письмо + сформировать документы

По назначению Activity Diagram частично пересекается с BPMN, поэтому важно понимать границу между ними.

Activity Diagram удобно использовать для описания flow внутри программной системы или отдельного алгоритма.

BPMN сильнее ориентирована на полноценное моделирование бизнес-процессов, участников, сообщений, событий и организационной ответственности.

То есть:

Activity Diagram - поток действий
BPMN - формализованный бизнес-процесс

State Machine Diagram

State Machine Diagram показывает, как объект меняет своё состояние под воздействием событий.

Основные элементы:

  • State;
  • Transition;
  • Event;
  • Guard;
  • Action;
  • Initial State;
  • Final State.

Например, заявка может проходить состояния:

Draft -> Submitted -> UnderReview -> Approved

или:

Draft -> Submitted -> UnderReview -> Rejected

Здесь важно не только перечислить возможные статусы, но и показать разрешённые переходы.

Например:

Draft -> Submitted
Submitted -> UnderReview
UnderReview -> Approved
UnderReview -> Rejected

State Machine позволяет явно показать, что переход:

Draft -> Approved

может быть запрещён.

Transition может зависеть от события.

Например:

Submit -> Draft -> Submitted
Approve -> UnderReview -> Approved
Reject -> UnderReview -> Rejected

Guard добавляет дополнительное условие перехода.

Например:

UnderReview -> Approved [documents_verified == true]

State Machine особенно полезна для сущностей со сложным жизненным циклом:

  • заявки;
  • заказы;
  • платежи;
  • документы;
  • сделки;
  • задачи.

Component Diagram

Component Diagram показывает крупные программные части системы и отношения между ними.

Например:

Frontend
Backend
Auth
Database
Cache
Queue
Object Storage

Для CRM-системы это может выглядеть так:

React Frontend -> Django Backend -> PostgreSQL
Django Backend -> Redis
Django Backend -> Keycloak
Django Backend -> RabbitMQ -> Celery Worker
Celery Worker -> MinIO

Здесь нас уже интересует не отдельный класс и не конкретный HTTP-запрос, а более крупное устройство системы.

Component Diagram помогает ответить на вопросы:

  • какие программные компоненты существуют;
  • за что они отвечают;
  • кто от кого зависит;
  • через какие интерфейсы они взаимодействуют.

По смыслу эта диаграмма близка к архитектурному моделированию, поэтому здесь появляется связь UML с C4 Model.

Но C4 делает акцент именно на уровнях архитектурного представления системы, тогда как Component Diagram является частью более общего UML.

Deployment Diagram

Deployment Diagram показывает, где физически или логически запускаются компоненты системы.

Основные элементы:

  • Node;
  • Artifact;
  • Execution Environment;
  • Deployment Relation.

Например:

VM / Docker Host -> Nginx -> Django backend containers -> Celery workers

Также можно показать:

Docker Host -> PostgreSQL container
Docker Host -> Redis container
Docker Host -> RabbitMQ container

Если Component Diagram описывает логическую структуру:

Frontend -> Backend -> Database

то Deployment Diagram показывает реальное размещение:

Browser -> Nginx -> backend-1 / backend-2 -> PostgreSQL server

Главное различие:

Component Diagram - из каких программных компонентов состоит система
Deployment Diagram - где и в каком окружении эти компоненты запускаются

Как выбрать нужную UML-диаграмму

Выбор начинается не с вопроса:

Какую диаграмму UML сейчас нарисовать?

а с вопроса:

Что именно я хочу объяснить?

Практическая схема:

Нужно показать пользователя и его цель? -> Use Case Diagram
Нужно показать порядок вызовов? -> Sequence Diagram
Нужно показать структуру объектов? -> Class Diagram
Нужно показать поток действий? -> Activity Diagram
Нужно показать состояния объекта? -> State Machine Diagram
Нужно показать программные компоненты? -> Component Diagram
Нужно показать инфраструктуру и размещение? -> Deployment Diagram

Одна система может иметь все эти диаграммы одновременно.

Например, для процесса подачи заявки:

Use Case -> Абитуриент может подать заявку
Activity -> как проходит процесс подачи
Sequence -> React -> Django -> PostgreSQL
Class -> Application, User, Program
State Machine -> Draft -> Submitted -> Approved
Component -> Frontend -> Backend -> Database
Deployment -> Nginx -> backend replicas -> PostgreSQL

Каждая диаграмма описывает один и тот же продукт, но отвечает на другой вопрос.

UML, BPMN и ERD

UML не нужно использовать вместо всех остальных способов моделирования.

У каждого инструмента есть своя область.

BPMN - бизнес-процессы
UML - структура и поведение программной системы
ERD - структура данных
C4 - архитектурные уровни системы

Например, процесс согласования заявки удобнее показать в BPMN.

Структуру таблиц Application, User и Program - в ERD.

Порядок взаимодействия React, Django и PostgreSQL - в Sequence Diagram.

Архитектуру frontend, backend, database, cache и queue - через C4 или Component Diagram.

Поэтому задача аналитика или разработчика не в том, чтобы выбрать одну "лучшую" нотацию.

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

Типичные ошибки

Одна из главных ошибок - попытка показать всё на одной диаграмме.

Например, одновременно:

пользователей + бизнес-процесс + классы + таблицы + API + Docker containers

Такая схема быстро становится нечитаемой.

Вторая ошибка - превращать Class Diagram в ERD.

Если на диаграмме показываются только таблицы, foreign keys и поля базы данных, скорее всего, нужна ERD.

Третья ошибка - добавлять implementation details в Use Case.

Use Case:

Подать заявку

не должен превращаться в:

POST /api/v1/applications -> serializer.validate() -> service.create()

Для этого больше подходит Sequence Diagram.

Четвёртая ошибка - рисовать Sequence Diagram без понятной ответственности участников.

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

И ещё одна распространённая проблема - использование UML только потому, что "в документации должна быть UML".

Диаграмма нужна тогда, когда она помогает ответить на конкретный вопрос.

Если после её создания система не стала понятнее, возможно, выбрана неправильная диаграмма или неверный уровень детализации.

Что важно запомнить

UML - это набор представлений одной программной системы.

Главную карту можно запомнить так:

Use Case - кто и зачем использует систему
Sequence - кто с кем взаимодействует во времени
Class - из каких объектов состоит программная модель
Activity - как идёт последовательность действий
State Machine - как меняются состояния объекта
Component - из каких крупных программных частей состоит система
Deployment - где эти части запускаются

Главная сила UML не в количестве обозначений.

Она в возможности посмотреть на одну систему с разных сторон и не пытаться смешать все уровни в одной схеме

Продолжить

  1. 01 BPMN: от бизнес-процесса до требований к системе Что такое BPMN, зачем моделировать бизнес-процессы и как читать простую диаграмму от начала до результата.
  2. 02 ERD и моделирование данных Подробное введение в ERD и моделирование данных. Разбираем сущности, атрибуты, первичные и внешние ключи, связи 1:1, 1:N и M:N, обязательность связей, нормализацию и переход от ERD к PostgreSQL и Django ORM.
  3. 03 State Machines: жизненный цикл сущностей Практическое введение в State Machine и моделирование жизненного цикла сущностей. Разбираем состояния, переходы, события, guard conditions, побочные эффекты и связь State Machine с BPMN, базой данных и API.
  4. 04 DFD: как данные проходят через систему Практическое введение в DFD и моделирование потоков данных. Разбираем внешние сущности, процессы, хранилища и потоки данных, Context Diagram, уровни декомпозиции, баланс между уровнями, связь DFD с API, безопасностью, BPMN и Sequence Diagram.
  5. 05 C4 Model: архитектура программной системы Практическое введение в C4 Model для описания архитектуры информационных систем. Разбираем уровни System Context, Container и Component, дополнительные Dynamic и Deployment Diagram, границы между ними и применение C4 для монолитов и микросервисов.
  6. 06 API Contracts: как системы договариваются о взаимодействии Практическое руководство по проектированию API-контрактов. Разбираем структуру HTTP API, ресурсы и action endpoints, request и response schemas, ошибки, OpenAPI, версионирование, совместимость, аутентификацию, авторизацию, webhook-контракты и безопасное изменение API для существующих consumers.
  7. 07 Event-Driven Modeling: события, очереди и асинхронные процессы Практическое руководство по Event-Driven Modeling и проектированию асинхронных взаимодействий. Разбираем команды и события, Producer, Broker и Consumer, очереди и routing, идемпотентность, порядок событий, retries, Dead Letter Queue, Transactional Outbox, eventual consistency и связь событий с BPMN и State Machine.
  8. 08 Как собрать BPMN, UML, ERD, C4 и API в одну проектную документацию Практическое руководство по сборке проектной документации информационной системы. Показываем, как связать BPMN, UML, ERD, State Machine, DFD, C4, API Contracts и Event-Driven Modeling так, чтобы каждая модель отвечала на свой вопрос и не дублировала остальные.

Обратная связь

Материал был полезен?

Нашли ошибку или неточность? Сообщить →

Начните вводить — найдём материал по всей библиотеке.