🎯 Обзор
Это руководство сопровождает вас при проектировании и моделировании системысистемы управления телефонными вызовамис использованиемдиаграмм состояний UML. Оно фокусируется нажизненном цикле исходящего вызова, показывая, как телефонная линия переходит из одного состояния в другое в ответ на действия пользователя и сетевые события.
Диаграмма отображает какпуть успешного вызова (успешная установка вызова), так инепредвиденные ситуации (ошибки, таймауты, занята линия), подчеркивая устойчивость, обработку исключений и четкие переходы между состояниями — ключевые принципы в системах реального времени.
🧩 Основные понятия в диаграммах состояний UML
Прежде чем приступить к изучению диаграммы, ознакомьтесь с основными понятиями UML:
| Понятие | Описание |
|---|---|
| Состояние | Состояние, в течение которого объект удовлетворяет определённым условиям или выполняет действия. |
| Переход | Переход из одного состояния в другое, вызванный событием. |
| Событие | Событие, вызывающее переход (например, снят трубку, действительный номер). |
| Самопереход | Переход, начинающийся и заканчивающийся в одном и том же состоянии (например, цифра(n) в то время как в Выбор номера). |
| Псевдосостояние | Специальные контрольные точки, такие как Инициализация или Финальное которые не являются реальными состояниями. |
| Составное состояние | Состояние, содержащее подсостояния (например, Ошибка состояние с Занято, Быстрое занято, Записанное сообщение). |
| Условие-охранник | Логическое выражение, которое должно быть истинным для выполнения перехода. |
✅ Совет профессионала: Используйте
событие [охранник] / действиесинтаксис в UML для документирования триггеров, условий и побочных эффектов.
🔄 Жизненный цикл исходящего вызова: пошаговый разбор
1. Фаза инициации и набора номера
🔹 Начальное псевдо-состояние → Бездействие
- Система начинается в состоянииНачальное псевдо-состояние.
- Еще нет активности; телефон находится на рычаге.
🔹 Бездействие → Тон (onHook)
- Событие:
onHook(пользователь снимает трубку) - Переход:
onHook → Тон - Действие: Генерировать сигнал набора; подготовиться к вводу цифры.
📌 Это первое видимое изменение состояния в жизненном цикле вызова.
🔹 Тон → Набор (digit(n))
- Событие:
digit(n)(пользователь вводит цифру) - Переход:
digit(n) → Набор - Состояние: Перейти в режим
Наборнабора.
🔹 Самопереход: Набор → Набор (digit(n))
- Событие:
digit(n)(введено несколько цифр) - Условие: Нет (всегда разрешено)
- Действие: Добавить цифру к набираемому номеру.
- Цель: Позволить непрерывный ввод цифр без выхода из состояния
Наборсостояния.
💡 Самопереходы необходимы для обработки последовательностей ввода, таких как телефонные номера.
2. Логика подключения и обработка исключений
🔹 Набор → Подключение (действительныйНомер)
- Событие:
действительныйНомер(полный номер проверен) - Переход:
действительныйНомер → Подключение - Действие: Инициировать установку вызова с сетью.
🔹 Набор → Записанное сообщение (недействительныйНомер)
- Событие:
недействительныйНомер(например, неправильная длина, недопустимый префикс) - Переход:
недействительныйНомер → Записанное сообщение - Действие: Воспроизвести предварительно записанное сообщение: «Номер, который вы набрали, не обслуживается.»
🔹 Подключение → Занято (номерЗанят)
- Событие:
номер занят - Переход:
numberBusy → сигнал занятости - Действие: Воспроизвести сигнал занятости; информировать пользователя, что линия занята.
🔹 Подключение → сигнал быстрой занятости (trunkBusy)
- Событие:
trunkBusy - Переход:
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
[*] --> 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 "Ошибка" as ErrorState {
state "BusyTone" as BusyTone
state "FastBusyTone" as FastBusyTone
state "Записанное сообщение" as RecordedMessage
}
' Внутренние действия
Idle : entry / Ожидание отбоя
DialTone : entry / Воспроизведение тонального сигнала
Dialing : entry / Сбор цифр
Connecting : entry / Перенаправление вызова
Ringing : entry / Звонок на удалённый телефон
Connected : entry / Установление сессии вызова
Disconnected : entry / Завершение сессии
@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 или поддерживаемые инструменты Markdown (VS Code, Obsidian и др.).
📚 Обзор и заключительные мысли
Этот Система управления телефонными вызовами машина состояний является реальным примером того, как UML может моделировать сложные, событийно управляемые системы с высокой надежностью.
✅ Что делает эту диаграмму эффективной:
- Четкий путь успеха с логичным потоком.
- Полное обращение с ошибками.
- Использование самопереходов, составных состояний, и ограничения.
- Визуальная ясность благодаря группировке и аннотации.
🛠️ Когда использовать этот шаблон:
- Телефонные системы
- Управление устройствами IoT
- Управление сеансами пользователей
- Движки рабочих процессов
- Встраиваемые системы с конечной логикой состояний
📝 Хотите расширить это?
Рассмотрите возможность добавления:
- Запись вызовов состояние (с
startRecording,stopRecordingсобытиями) - Переадресация вызовов логика (условная маршрутизация)
- Ожидание вызова поддержка (параллельные состояния)
- Передача вызова в качестве подсостояния
Подключено - История состояний (мелкая/глубокая история) для повторного входа после прерывания
📌 Финальная рекомендация
Всегда моделируйте как успешные, так и неудачные пути.
Машина состояний, которая обрабатывает только «счастливые пути», неполна и подвержена ошибкам в производственной среде.
Используйте это руководство как шаблон для моделирования любой системы в реальном времени, где переходы состояний, события, и устойчивость к ошибкам имеет значение.
✅ Готовы генерировать, визуализировать или расширять?
👉 Скопируйте PlantUML или Mermaid код выше и интегрируйте его в вашу документацию, диаграммы архитектуры или документы по проектированию системы.
Сообщите мне, если вам нужна версия PDF, интерактивная диаграмма, или интеграция в более крупную модель системы (например, с компонентами или диаграммами последовательности)!
📘 «Лучшие системы не просто правильные — они предвидят сбои.»
— Проектирование с использованием машин состояний UML










