🎯 概述
本指南將帶您了解設計與建模一個電話呼叫控制系統的過程,使用UML狀態機圖。重點在於外撥呼叫生命週期,說明電話線路如何根據使用者操作與網路事件在不同狀態之間轉換。
該圖表同時呈現順利路徑(成功建立通話)與不順利路徑(錯誤、逾時、線路忙),強調系統的穩健性、例外處理與明確的狀態轉換——這正是即時通訊系統中的關鍵原則。
🧩 UML狀態機的核心概念
在深入圖表之前,請先了解這些基礎的UML概念:
| 概念 | 描述 |
|---|---|
| 狀態 | 物件在滿足特定條件或執行動作期間所處的狀態。 |
| 轉換 | 由事件觸發,從一個狀態轉變到另一個狀態的過程。 |
| 事件 | 引發轉換的發生事件(例如 掛機, 有效號碼). |
| 自我轉換 | 從同一狀態開始並結束的轉換(例如 數位(n) 在…期間 撥號). |
| 偽狀態 | 特殊控制點,例如 初始 或 最終 這些並非實際狀態。 |
| 複合狀態 | 包含子狀態的狀態(例如 錯誤 狀態與 忙音, 快速忙音, 錄音訊息). |
| 守衛條件 | 一個布林表達式,必須為真才能觸發轉移。 |
✅ 專業提示: 使用
事件 [守衛] / 動作UML 語法,用於記錄觸發條件、條件與副作用。
🔄 外撥電話生命週期:逐步分解
1. 啟動與撥號階段
🔹 初始偽狀態 → 空閒
-
系統從 初始偽狀態.
-
尚未有任何活動;電話掛在鉤上。
🔹 空閒 → 拨号音 (掛機)
-
事件:
掛機(使用者拿起聽筒) -
轉移:
掛機 → 拨号音 -
動作: 產生撥號音;準備接收數字輸入。
📌 這是通話生命週期中的第一次可見狀態變更。
🔹 拨号音 → 拨號中 (輸入數字(n))
-
事件:
輸入數字(n)(使用者輸入一個數字) -
轉移:
輸入數字(n) → 拨號中 -
狀態: 進入
撥號中模式。
🔹 自轉移:撥號中 → 拨號中 (輸入數字(n))
-
事件:
輸入數字(n)(輸入多個數字) -
保護條件: 無(始終允許)
-
動作: 將數字附加到正在撥打的號碼上。
-
目的: 允許連續輸入數字,而無需離開
撥號狀態。
💡 自我轉移對於處理電話號碼之類的輸入序列至關重要。
2. 連接邏輯與例外處理
🔹 拨号 → 连接(有效号码)
-
事件:
有效号码(完整號碼已驗證) -
轉移:
有效号码 → 连接 -
動作: 啟動與網絡的呼叫設置。
🔹 拨号 → 录音消息(无效号码)
-
事件:
无效号码(例如:長度錯誤、無效前綴) -
轉移:
无效号码 → 录音消息 -
動作: 播放預錄訊息: “您撥打的號碼目前無法使用。”
🔹 連接 → 忙音(號碼忙)
-
事件:
號碼忙碌 -
轉換:
號碼忙碌 → 忙音 -
動作:播放忙音;通知使用者線路已被佔用。
🔹 連線中 → 快速忙音(中繼線忙碌)
-
事件:
中繼線忙碌 -
轉換:
中繼線忙碌 → 快速忙音 -
動作:播放快速忙音;表示網路擁塞。
⚠️ 注意:這些是錯誤狀態會中斷正常流程的狀態。必須妥善處理。
3. 逾時與警告機制
🔹 拔號中 → 警告(逾時)
-
事件:
逾時在30秒無動作後 -
轉換:
逾時 → 警告 -
動作:播放警告提示音;通知使用者繼續操作或掛機。
🔹 警告 → 逾時(逾時)
-
事件:
逾時10秒後再次 -
轉移:
timeout → 超時 -
動作:取消撥號嘗試;返回到
空閒.
⏱️ 超時邏輯可防止無限等待,並改善使用者體驗。
4. 通話中與中斷
🔹 連接中 → 鈴響(已路由)
-
事件:
已路由(網路成功路由通話) -
轉移:
已路由 → 鈴響 -
動作:發送鈴響信號給被叫方。
🔹 鈴響 → 已連接(被叫方接聽)
-
事件:
被叫方接聽 -
轉移:
被叫方接聽 → 已連接 -
動作:建立音訊連接;開始通話錄音(如已啟用)。
🔹 已連接 → 已中斷(掛機或被叫方掛機)
-
中斷的兩種途徑:
-
使用者掛機:
掛機 → 已中斷 -
對方掛斷:
被叫電話掛斷 → 已斷開
-
🔄 兩個轉移都導向
已斷開在達到最終狀態.
🔹 已斷開 → 最終狀態
-
事件: 無(隱式或透過清理動作)
-
轉移:
已斷開 → 最終 -
動作: 清理資源,記錄通話時間,更新統計資料。
✅ 最終狀態標示通話生命週期的結束。
🎨 演示清晰度的視覺設計原則
讓複雜的狀態機具備可讀性和可維護性:
| 原則 | 實作 |
|---|---|
| 核心正常流程 | 將主要流程(空閒 → 拨号音 → 拨号中 → 連接中 → 鈴響 → 已連接)保持為一條清晰的垂直或水平線。 |
| 例外情況向外分支 | 將錯誤狀態(忙音、快速忙音、錄音訊息)作為側邊分支放置。 |
| 將相關狀態分組 | 使用 複合狀態 用於錯誤狀況(見下文)。 |
| 智慧地使用偽狀態 | 初始和最終應明確標記。 |
| 避免交叉轉移 | 避免箭頭重疊;必要時使用正交區域。 |
🔧 高級建模技術
✅ 組合狀態:「錯誤」分組
不要逐一列出忙音, 快速忙音,以及錄音訊息作為獨立狀態,將它們歸類於一個組合狀態稱為錯誤:
[錯誤]
├── 忙音
├── 快速忙音
└── 錄音訊息
-
進入動作:播放錯誤提示音或訊息。
-
退出動作:返回至
撥號音或閒置在使用者回應後。
✅ 優勢:減少視覺混亂並提升可擴展性。
✅ 保護條件(可選增強功能)
新增保護條件以精細化轉換:
數字(n) [number.length < 15] → 拨號
有效號碼 [number.isInternational] → 連接中
🛠️ 保護條件可防止無效轉換,並支援條件邏輯。
📌 重點總結:複雜狀態機的最佳實務
| 實踐 | 為何如此重要 |
|---|---|
| 建模不順利的路徑 | 真實系統會失敗。設計時應考慮 無效號碼, 逾時, 中繼線忙 確保可靠性。 |
| 使用動作表達式 | 包含 / logCallAttempt() 或 / playTone() 以顯示副作用。 |
| 保持事件詳細且以動作為導向 | 使用 掛機, 已路由, 被呼叫電話已接聽而不是e1, e2. |
| 明確命名狀態 | 避免狀態1, 狀態2。使用撥號中, 響鈴, 已連接. |
| 記錄假設 | 例如,“閒置30秒後逾時”應在註釋中註明。 |
💻 程式碼產生:PlantUML 與 Mermaid
以下是可立即使用的程式碼區塊用於以您偏好的格式產生此圖表。
✅ PlantUML 程式碼
@startuml
[*] –> 空閒
空閒 –> 拨号音 : 挂机
拨号音 –> 拨号中 : 按下數字(n)
撥號中 –> 拨號中 : 按下數字(n) ‘ 自轉移
撥號中 –> 連接中 : 輸入有效號碼
撥號 –> 录制訊息 : 電話號碼無效
撥號 –> 警告 : 超時
警告 –> 超時 : 超時
連接中 –> 鈴響 : 已轉接
連接中 –> 忙音 : 號碼忙
連接中 –> 快速忙音 : 中繼忙
鈴響 –> 已連接 : 被叫電話接聽
已連接 –> 已掛機 : 挂機
已連接 –> 已掛機 : 被叫電話掛機
已掛機 –> [*] : 清理
狀態 「錯誤」 為 ErrorState {
狀態 「忙音」 為 BusyTone
狀態 「快速忙音」 為 FastBusyTone
狀態 「錄製訊息」 為 RecordedMessage
}
‘ 內部動作
空閒 : 進入 / 等待掛機
撥號音 : 進入 / 播放撥號音
撥號 : 進入 / 收集數字
連接中 : 進入 / 轉接電話
鈴響 : 進入 / 鈴響遠端電話
已連接 : 進入 / 建立通話會話
已掛機 : 進入 / 終止會話
@enduml
📥 使用方法: 貼上至 PlantUML Live 或您的 IDE 插件。
✅ Mermaid 程式碼

stateDiagram-v2
[*] --> 空閒
空閒 --> 拨号音 : 挂機
拨号音 --> 拨號中 : 數字(n)
拨號中 --> 拨號中 : 數字(n) ' 自轉移
拨號中 --> 連接中 : 有效號碼
拨號中 --> 录音訊息 : 無效號碼
拨號中 --> 提醒 : 超時
提醒 --> 超時 : 超時
連接中 --> 鈴響 : 路由成功
連接中 --> 忙音 : 號碼忙
連接中 --> 快速忙音 : 中繼忙
鈴響 --> 已連接 : 對方接聽
已連接 --> 已斷線 : 挂機
已連接 --> 已斷線 : 對方掛機
已斷線 --> [*] : 清理
state 錯誤 {
忙音
快速忙音
录音訊息
}
連接中 --> 忙音 : 號碼忙
連接中 --> 快速忙音 : 中繼忙
拨號中 --> 录音訊息 : 無效號碼
note right of 忙音
播放標準忙音
end note
note right of 快速忙音
播放快速忙音(網路擁塞)
end note
note right of 录音訊息
播放錄音訊息:「號碼未提供服務。」
end note
note right of 超時
40秒後取消撥號嘗試
end note
📥 如何使用:貼上至Mermaid Live Editor或支援的 Markdown 工具(VS Code、Obsidian 等)。
📚 總結與最終想法
這個電話通訊呼叫控制系統狀態機是一個現實世界中的範例說明 UML 如何以高可靠性模擬複雜的事件驅動系統。
✅ 這個圖表有效的關鍵:
-
清晰的正常流程具有邏輯流程。
-
全面的錯誤處理.
-
使用了自轉移, 複合狀態,以及守衛.
-
透過分組與註解.
🛠️ 何時使用此模式:
-
電話系統
-
物聯網裝置控制
-
使用者會話管理
-
工作流程引擎
-
具備有限狀態邏輯的嵌入式系統
📝 想要擴展此內容嗎?
可考慮新增:
-
通話錄音 狀態(包含
startRecording,stopRecording事件) -
轉接通話 邏輯(條件路由)
-
通話等待 支援(平行狀態)
-
通話轉移 作為 的子狀態
已連接 -
狀態歷史 (淺層/深層歷史)用於中斷後重新進入
📌 最終建議
始終建模成功與失敗兩種路徑。
僅處理「順利路徑」的狀態機是不完整的,且在生產環境中容易出現錯誤。
將此指南作為 範本 用於建模任何即時系統,其中 狀態轉換, 事件,以及錯誤韌性這很重要。
✅ 準備好產生、視覺化或擴展了嗎?
👉 複製上方的PlantUML或Mermaid程式碼,並將其整合到您的文件、架構圖或系統設計文件中。
如果您需要PDF版本, 互動式圖表,或整合到更大的系統模型中(例如,搭配元件圖或序列圖)!
📘 「最好的系統不僅僅是正確的——它們預見失敗。」
— 使用UML狀態機進行設計











