🎯 Обзор
Это руководство сопровождает вас при проектировании и моделировании системысистемы управления телефонными вызовамис использованиемдиаграмм состояний UML. Оно фокусируется нажизненном цикле исходящего вызова, показывая, как телефонная линия переходит между состояниями в ответ на действия пользователя и сетевые события.
Диаграмма отражает какпуть успешного вызова (успешная установка вызова), так инепредвиденные ситуации (ошибки, таймауты, занята линия), подчеркивая устойчивость, обработку исключений и четкие переходы между состояниями — ключевые принципы в системах реального времени.
🧩 Основные понятия в диаграммах состояний UML
Прежде чем приступить к изучению диаграммы, ознакомьтесь с основными понятиями UML:
| Понятие | Описание |
|---|---|
| Состояние | Состояние, в течение которого объект удовлетворяет определённым условиям или выполняет действия. |
| Переход | Изменение одного состояния в другое, инициированное событием. |
| Событие | Событие, вызывающее переход (например, снят с аппарата, действительный номер). |
| Самопереход | Переход, начинающийся и заканчивающийся в одном и том же состоянии (например, цифра(n) в то время как в Выбор номера). |
| Псевдосостояние | Специальные контрольные точки, такие как Инициализация или Финальное которые на самом деле не являются состояниями. |
| Составное состояние | Состояние, содержащее подсостояния (например, Ошибка состояние с Занято, Быстрое занято, Записанное сообщение). |
| Условие-охранник | Булево выражение, которое должно быть истинным для выполнения перехода. |
✅ Совет профессионала: Используйте
событие [охранник] / действиесинтаксис в UML для документирования триггеров, условий и побочных эффектов.
🔄 Жизненный цикл исходящего вызова: Пошаговое разбиение
1. Фаза инициации и набора номера
🔹 Начальное псевдо-состояние → Бездействие
-
Система начинается в состоянииНачальное псевдо-состояние.
-
Еще нет активности; телефон находится на рычаге.
🔹 Бездействие → Тон (onHook)
-
Событие:
onHook(пользователь снимает трубку) -
Переход:
onHook → Тон -
Действие: Генерировать сигнал вызова; подготовиться к вводу цифры.
📌 Это первое видимое изменение состояния в жизненном цикле вызова.
🔹 Тон → Ввод цифры (digit(n))
-
Событие:
digit(n)(пользователь вводит цифру) -
Переход:
digit(n) → Ввод цифры -
Состояние: Перейти в режим
Ввод цифрырежима.
🔹 Самопереход: Ввод цифры → Ввод цифры (digit(n))
-
Событие:
digit(n)(введено несколько цифр) -
Условие: Нет (всегда разрешено)
-
Действие: Добавить цифру к набираемому номеру.
-
Цель: Позволить непрерывный ввод цифр без выхода из состояния
Наборсостояния.
💡 Самопереходы необходимы для обработки последовательностей ввода, таких как телефонные номера.
2. Логика подключения и обработка исключений
🔹 Набор → Подключение (действительныйНомер)
-
Событие:
действительныйНомер(полный номер проверен) -
Переход:
действительныйНомер → Подключение -
Действие: Инициировать установку вызова с сетью.
🔹 Набор → Записанное сообщение (недействительныйНомер)
-
Событие:
недействительныйНомер(например, неправильная длина, недопустимый префикс) -
Переход:
недействительныйНомер → Записанное сообщение -
Действие: Воспроизвести предварительно записанное сообщение: «Номер, который вы набрали, не обслуживается.»
🔹 Подключение → Занято (номерЗанят)
-
Событие:
номер занят -
Переход:
номер занят → сигнал занятости -
Действие:Воспроизвести сигнал занятости; информировать пользователя, что линия занята.
🔹 Подключение → быстрый сигнал занятости (trunkBusy)
-
Событие:
транковый номер занят -
Переход:
транковый номер занят → быстрый сигнал занятости -
Действие:Воспроизвести быстрый сигнал занятости; указать на перегрузку сети.
⚠️ Примечание: Это состояния ошибок которые нарушают нормальный ход работы. Их необходимо обрабатывать корректно.
3. Механизм таймаута и предупреждения
🔹 Ввод номера → Предупреждение (таймаут)
-
Событие:
таймаутчерез 30 секунд бездействия -
Переход:
таймаут → Предупреждение -
Действие:Воспроизвести предупреждающий сигнал; уведомить пользователя продолжить или положить трубку.
🔹 Предупреждение → Таймаут (таймаут)
-
Событие:
таймаутснова через 10 секунд -
Переход:
тайм-аут → Тайм-аут -
Действие: Отменить попытку вызова; вернуться к
Ожидание.
⏱️ Логика тайм-аута предотвращает бесконечное ожидание и улучшает пользовательский опыт.
4. Активный вызов и отключение
🔹 Подключение → Звонок (перенаправлено)
-
Событие:
перенаправлено(сеть успешно направляет вызов) -
Переход:
перенаправлено → Звонок -
Действие: Отправить сигнал звонка вызываемой стороне.
🔹 Звонок → Подключено (вызов принят)
-
Событие:
вызов принят -
Переход:
вызов принят → Подключено -
Действие: Установить аудиосоединение; начать запись вызова (если включено).
🔹 Подключено → Отключено (снято трубку ИЛИ вызываемая сторона повесила трубку)
-
Два пути отключения:
-
Пользователь повесил трубку:
снято трубку → Отключено -
Другая сторона снимает трубку:
вызов завершен → Отключено
-
🔄 Оба перехода приводят к
Отключенодо достиженияФинальное состояние.
🔹 Отключено → Финальное состояние
-
Событие: Нет (неявно или через действие очистки)
-
Переход:
Отключено → Финальное -
Действие: Очистить ресурсы, записать продолжительность вызова, обновить статистику.
✅ Финальное состояние означает конец жизненного цикла вызова.
🎨 Принципы визуального дизайна для ясности
Чтобы сделать сложные машины состояний читаемыми и поддерживаемыми:
| Принцип | Реализация |
|---|---|
| Основной путь (счастливый путь) | Сохраняйте основной поток (Ожидание → Тон вызова → Ввод номера → Соединение → Звонок → Соединение) в виде чистой вертикальной или горизонтальной линии. |
| Отклоняйтесь наружу для исключений | Размещайте состояния ошибок (Занято, Быстрое занято, Записанное сообщение) как боковые ветви. |
| Группируйте связанные состояния | Используйтесоставные состояния для условий ошибок (см. ниже). |
| Разумно используйте псевдосостояния | Инициальный и Финальный должен быть четко обозначен. |
| Избегайте пересекающихся переходов | Не допускайте пересечения стрелок; при необходимости используйте ортогональные области. |
🔧 Расширенные методы моделирования
✅ Составное состояние: группировка «Ошибка»
Вместо перечисления BusyTone, FastBusyTone, и RecordedMessage в качестве отдельных состояний, объедините их в составное состояние называемое Ошибка:
[Ошибка]
├── BusyTone
├── FastBusyTone
└── RecordedMessage
-
Действие входа: Воспроизвести сигнал ошибки или сообщение.
-
Действие выхода: Вернуться к
DialToneилиIdleпосле ответа пользователя.
✅ Преимущество:Уменьшает визуальную загруженность и улучшает масштабируемость.
✅ Условия-ограничения (необязательные улучшения)
Добавьте условия-ограничения для уточнения переходов:
цифра(n) [number.length < 15] → Ввод номера
валидныйНомер [number.isInternational] → Соединение
🛠️ Условия-ограничения предотвращают недопустимые переходы и поддерживают условную логику.
📌 Ключевые выводы: лучшие практики для сложных машин состояний
| Практика | Почему это важно |
|---|---|
| Моделирование неприятных путей | Реальные системы выходят из строя. Проектирование для некорректныйНомер, тайм-аут, линия занята гарантирует надежность. |
| Используйте выражения действий | Включите / logCallAttempt() или / playTone() для отображения побочных эффектов. |
| Держите события подробными и ориентированными на действия | Используйте снятоСлушком, перенаправлено, вызванныйТелефонОтвечаетвместоe1, e2. |
| Четко назовите состояния | ИзбегайтеСостояние1, Состояние2. ИспользуйтеВвод номера, Звонок, Подключено. |
| Документируйте предположения | Например, «Тайм-аут после 30 секунд неактивности» следует отметить в комментариях. |
💻 Генерация кода: PlantUML и Mermaid
Вотготовые блоки кодадля генерации этой диаграммы в предпочитаемом вами формате.
✅ Код PlantUML
@startuml
[*] –> Пусто
Пусто –> Сигнал: onHook
Сигнал –> Ввод номера: цифра(n)
Ввод номера –> Ввод номера: цифра(n) ‘ Самопереход
Ввод номера –> Подключение: действительный номер
Вызов –> Сообщение для записи : недопустимыйНомер
Вызов –> Предупреждение : тайм-аут
Предупреждение –> Тайм-аут : тайм-аут
Соединение –> Звонок : перенаправлено
Соединение –> Занято : номерЗанят
Соединение –> Быстрое занято : трассаЗанята
Звонок –> Соединено : вызываемыйТелефонОтветил
Соединено –> Разъединено : положили трубку
Соединено –> Разъединено : вызываемыйТелефонПовесил
Разъединено –> [*] : очистка
состояние «Ошибка» как ErrorState {
состояние «Занято» как BusyTone
состояние «Быстрое занято» как FastBusyTone
состояние «Записанное сообщение» как RecordedMessage
}
‘ Внутренние действия
Пустой : вход / Ожидание отбоя
Тон вызова : вход / Воспроизведение тона вызова
Вызов : вход / Сбор цифр
Соединение : вход / Перенаправление вызова
Звонок : вход / Звонок на удаленный телефон
Соединено : вход / Установка сессии вызова
Разъединено : вход / Остановка сессии
@enduml
📥 Как использовать: Вставьте в PlantUML Live или ваш плагин IDE.
✅ Код Mermaid

stateDiagram-v2
[*] --> Idle
Idle --> DialTone : onHook
DialTone --> Dialing : digit(n)
Dialing --> Dialing : digit(n) ' Самопереход
Dialing --> Connecting : validNumber
Dialing --> RecordedMessage : invalidNumber
Dialing --> Warning : timeout
Warning --> Timeout : timeout
Connecting --> Ringing : routed
Connecting --> BusyTone : numberBusy
Connecting --> FastBusyTone : trunkBusy
Ringing --> Connected : calledPhoneAnswers
Connected --> Disconnected : onHook
Connected --> Disconnected : calledPhoneHangsUp
Disconnected --> [*] : cleanup
state Error {
BusyTone
FastBusyTone
RecordedMessage
}
Connecting --> BusyTone : numberBusy
Connecting --> FastBusyTone : trunkBusy
Dialing --> RecordedMessage : invalidNumber
note right of BusyTone
Воспроизвести стандартный сигнал занятости
end note
note right of FastBusyTone
Воспроизвести быстрый сигнал занятости (перегрузка сети)
end note
note right of RecordedMessage
Воспроизвести записанное сообщение: "Номер не обслуживается."
end note
note right of Timeout
Попытка вызова отменена через 40 секунд
end note
📥 Как использовать: Вставьте в Редактор Mermaid Live или поддерживаемые инструменты Markdown (VS Code, Obsidian и др.).
📚 Обзор и заключительные мысли
Эта Система управления телефонными вызовами машина состояний является реальным примером того, как UML может моделировать сложные, событийно управляемые системы с высокой надежностью.
✅ Что делает эту диаграмму эффективной:
-
Четкий путь выполнения с логическим потоком.
-
Полное обращение с ошибками.
-
Использование самопереходов, составных состояний, и ограничителей.
-
Визуальная ясность благодаря группировке и аннотациям.
🛠️ Когда использовать этот шаблон:
-
Телекоммуникационные системы
-
Управление устройствами IoT
-
Управление сеансами пользователей
-
Движки рабочих процессов
-
Встраиваемые системы с конечной логикой состояний
📝 Хотите расширить это?
Рассмотрите возможность добавления:
-
Запись вызовов состояние (с
startRecording,stopRecordingсобытиями) -
Переадресация вызовов логика (условная маршрутизация)
-
Ожидание вызова поддержка (параллельные состояния)
-
Передача вызова как подсостояние
Подключено -
История состояний (история поверхностного/глубокого уровня) для повторного входа после прерывания
📌 Окончательная рекомендация
Всегда моделируйте как успешные, так и неудачные пути.
Машина состояний, которая обрабатывает только «счастливые пути», неполна и подвержена ошибкам в продакшене.
Используйте это руководство как шаблон для моделирования любой системы в реальном времени, где переходы состояний, события, и устойчивость к ошибкам важно.
✅ Готовы генерировать, визуализировать или расширять?
👉 Скопируйте PlantUML или Mermaid код выше и интегрируйте его в вашу документацию, диаграммы архитектуры или документы по проектированию системы.
Сообщите мне, если вам нужна версия PDF, интерактивная диаграмма, или интеграция в более крупную модель системы (например, с компонентами или диаграммами последовательности)!
📘 «Лучшие системы не просто правильные — они предвидят сбои.»
— Проектирование с использованием машин состояний UML












