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 не в количестве обозначений.
Она в возможности посмотреть на одну систему с разных сторон и не пытаться смешать все уровни в одной схеме