🎯 Tổng quan
Hướng dẫn này dẫn dắt bạn qua quá trình thiết kế và mô hình hóa mộtHệ thống điều khiển cuộc gọi điện thoạibằng cách sử dụngSơ đồ Máy trạng thái UML. Nó tập trung vàochu kỳ sống cuộc gọi đi, minh họa cách một đường dây điện thoại chuyển đổi giữa các trạng thái phản ứng với hành động của người dùng và các sự kiện mạng.
Sơ đồ này ghi lại cả haiđường đi thuận lợi (thiết lập cuộc gọi thành công) vàđường đi không thuận lợi (lỗi, hết thời gian chờ, đường dây bận), nhấn mạnh tính bền vững, xử lý ngoại lệ và các chuyển trạng thái rõ ràng – những nguyên tắc cốt lõi trong các hệ thống truyền thông thời gian thực.
🧩 Các khái niệm cốt lõi trong Máy trạng thái UML
Trước khi đi sâu vào sơ đồ, hãy hiểu rõ các khái niệm UML nền tảng sau:
| Khái niệm | Mô tả |
|---|---|
| Trạng thái | Một trạng thái trong đó một đối tượng thoả mãn các điều kiện nhất định hoặc thực hiện các hành động. |
| Chuyển tiếp | Một sự thay đổi từ trạng thái này sang trạng thái khác, được kích hoạt bởi một sự kiện. |
| Sự kiện | Một sự kiện gây ra chuyển tiếp (ví dụ nhưonHook, validNumber). |
| Chuyển tiếp tự thân | Một chuyển tiếp bắt đầu và kết thúc ở cùng một trạng thái (ví dụ nhưchữ số(n)trong khi ở trongGọi). |
| Trạng thái giả | Các điểm điều khiển đặc biệt nhưBan đầuhoặcCuối cùngmà không phải là các trạng thái thực sự. |
| Trạng thái hợp thành | Một trạng thái chứa các trạng thái con (ví dụ nhưLỗitrạng thái vớiTone bận, Tone bận nhanh, Tin nhắn ghi âm). |
| Điều kiện bảo vệ | Một biểu thức logic phải đúng để chuyển tiếp xảy ra. |
✅ Mẹo hay:Sử dụng
sự kiện [điều kiện bảo vệ] / hành độngcú pháp trong UML để ghi chú các sự kiện kích hoạt, điều kiện và hệ quả phụ.
🔄 Chu kỳ sống cuộc gọi ra: Phân tích từng bước
1. Giai đoạn khởi tạo và gọi
🔹 Trạng thái giả ban đầu → Đang chờ
- Hệ thống khởi động ở trạng thái Trạng thái giả ban đầu.
- Chưa có hoạt động nào; điện thoại đang để trên giá đỡ.
🔹 Đang chờ → Tín hiệu chuông (đã nhấc máy)
- Sự kiện:
đã nhấc máy(người dùng nhấc máy lên) - Chuyển tiếp:
đã nhấc máy → tín hiệu chuông - Hành động: Tạo tín hiệu chuông; chuẩn bị cho đầu vào chữ số.
📌 Đây là thay đổi trạng thái đầu tiên có thể quan sát được trong chu kỳ cuộc gọi.
🔹 Tín hiệu chuông → Đang gọi (chữ số(n))
- Sự kiện:
chữ số(n)(người dùng nhập một chữ số) - Chuyển tiếp:
chữ số(n) → Đang gọi - Trạng thái: Chuyển sang
Đang gọichế độ.
🔹 Chuyển tiếp tự thân: Đang gọi → Đang gọi (chữ số(n))
- Sự kiện:
chữ số(n)(nhiều chữ số được nhập) - Điều kiện: Không (luôn được phép)
- Hành động: Thêm chữ số vào số đang được gọi.
- Mục đích: Cho phép nhập liên tục các chữ số mà không cần rời khỏi trạng thái
Đang gọitrạng thái.
💡 Các chuyển tiếp tự thân là thiết yếu để xử lý các chuỗi đầu vào như số điện thoại.
2. Logic kết nối và xử lý ngoại lệ
🔹 Đang gọi → Đang kết nối (số hợp lệ)
- Sự kiện:
số hợp lệ(số hoàn chỉnh đã được xác minh) - Chuyển tiếp:
số hợp lệ → Đang kết nối - Hành động: Khởi tạo thiết lập cuộc gọi với mạng lưới.
🔹 Đang gọi → Tin nhắn đã ghi (số không hợp lệ)
- Sự kiện:
số không hợp lệ(ví dụ: độ dài sai, tiền tố không hợp lệ) - Chuyển tiếp:
số không hợp lệ → Tin nhắn đã ghi - Hành động: Phát tin nhắn đã ghi trước: “Số bạn vừa gọi hiện không hoạt động.”
🔹 Đang kết nối → Tín hiệu bận (số bận)
- Sự kiện:
số bận - Chuyển tiếp:
số bận → Tiếng bíp bận - Hành động: Phát tiếng bíp bận; thông báo cho người dùng đường dây đang bận.
🔹 Đang kết nối → Tiếng bíp bận nhanh (trunkBusy)
- Sự kiện:
trunkBusy - Chuyển tiếp:
trunkBusy → Tiếng bíp bận nhanh - Hành động: Phát tiếng bíp bận nhanh; cho biết mạng đang quá tải.
⚠️ Ghi chú: Đây là trạng thái lỗi là những trạng thái làm gián đoạn luồng hoạt động bình thường. Chúng cần được xử lý một cách trơn tru.
3. Cơ chế hết thời gian & cảnh báo
🔹 Đang quay số → Cảnh báo (hết thời gian)
- Sự kiện:
hết thời giansau 30 giây không hoạt động - Chuyển tiếp:
hết thời gian → Cảnh báo - Hành động: Phát tiếng bíp cảnh báo; thông báo cho người dùng tiếp tục hoặc treo máy.
🔹 Cảnh báo → Hết thời gian (hết thời gian)
- Sự kiện:
hết thời gianlại sau 10 giây - Chuyển tiếp:
timeout → Timeout - Hành động: Hủy bỏ thử gọi; quay lại
Ngưng hoạt động.
⏱️ Logic thời gian chờ giúp ngăn chặn việc chờ đợi vô hạn và cải thiện trải nghiệm người dùng.
4. Cuộc gọi đang hoạt động và ngắt kết nối
🔹 Đang kết nối → Bắt máy (được định tuyến)
- Sự kiện:
được định tuyến(mạng đã định tuyến cuộc gọi thành công) - Chuyển tiếp:
được định tuyến → Bắt máy - Hành động: Gửi tín hiệu bắt máy đến bên được gọi.
🔹 Bắt máy → Kết nối (điện thoại được gọi trả lời)
- Sự kiện:
điện thoại được gọi trả lời - Chuyển tiếp:
điện thoại được gọi trả lời → Kết nối - Hành động: Thiết lập kết nối âm thanh; bắt đầu ghi âm cuộc gọi (nếu được bật).
🔹 Đã kết nối → Ngắt kết nối (treo máy HOẶC điện thoại được gọi ngắt kết nối)
- Hai con đường để ngắt kết nối:
- Người dùng treo máy:
treo máy → Ngắt kết nối - Đối phương ngắt cuộc gọi:
calledPhoneHangsUp → Ngắt kết nối
- Người dùng treo máy:
🔄 Cả hai chuyển tiếp đều dẫn đến
Ngắt kết nốitrước khi đạt đếnTrạng thái cuối.
🔹 Ngắt kết nối → Trạng thái cuối
- Sự kiện: Không (ngầm định hoặc thông qua hành động dọn dẹp)
- Chuyển tiếp:
Ngắt kết nối → Cuối - Hành động: Dọn dẹp tài nguyên, ghi lại thời lượng cuộc gọi, cập nhật thống kê.
✅ Trạng thái cuối biểu thị kết thúc chu kỳ cuộc gọi.
🎨 Nguyên tắc thiết kế trực quan để rõ ràng
Để làm cho các máy trạng thái phức tạp dễ đọc và dễ bảo trì:
| Nguyên tắc | Thực hiện |
|---|---|
| Đường đi chính (Happy Path) trung tâm | Giữ luồng chính (Ngưng → Tín hiệu gọi → Đang gọi → Đang kết nối → Đang reo → Đã kết nối) như một đường thẳng dọc hoặc ngang rõ ràng. |
| Tách nhánh ra ngoài cho các ngoại lệ | Đặt các trạng thái lỗi (BusyTone, FastBusyTone, Tin nhắn ghi âm) như các nhánh phụ. |
| Nhóm các trạng thái liên quan | Sử dụng trạng thái hợp thành cho các điều kiện lỗi (xem bên dưới). |
| Sử dụng trạng thái giả một cách khôn khéo | Ban đầu và Cuối cùng phải được đánh dấu rõ ràng. |
| Tránh các chuyển tiếp chéo nhau | Giữ cho các mũi tên không chồng chéo lên nhau; sử dụng các vùng vuông góc nếu cần thiết. |
🔧 Các kỹ thuật mô hình hóa nâng cao
✅ Trạng thái tổng hợp: Nhóm “Lỗi”
Thay vì liệt kê BusyTone, FastBusyTone, và RecordedMessage như các trạng thái riêng biệt, hãy nhóm chúng dưới một trạng thái tổng hợp gọi là Lỗi:
[Lỗi]
├── BusyTone
├── FastBusyTone
└── RecordedMessage
- Hành động vào: Phát âm thanh lỗi hoặc tin nhắn.
- Hành động thoát: Trở về
DialTonehoặcIdlesau phản hồi của người dùng.
✅ Lợi ích:Giảm sự lộn xộn về mặt thị giác và cải thiện khả năng mở rộng.
✅ Điều kiện bảo vệ (Cải tiến tùy chọn)
Thêm điều kiện bảo vệ để tinh chỉnh các chuyển tiếp:
digit(n) [number.length < 15] → Đang gọi
validNumber [number.isInternational] → Đang kết nối
🛠️ Điều kiện bảo vệ ngăn chặn các chuyển tiếp không hợp lệ và hỗ trợ logic điều kiện.
📌 Những điểm chính cần lưu ý: Các thực hành tốt nhất cho máy trạng thái phức tạp
| Thực hành | Tại sao điều đó quan trọng |
|---|---|
| Mô hình hóa các đường đi không mong muốn | Các hệ thống thực tế thường thất bại. Thiết kế cho số không hợp lệ, hết thời gian, kênh bận đảm bảo độ tin cậy. |
| Sử dụng biểu thức hành động | Bao gồm / logLanGoi() hoặc / playTone() để thể hiện các hiệu ứng phụ. |
| Giữ các sự kiện rõ ràng và hướng đến hành động | Sử dụng treo máy, được định tuyến, điện thoại được gọi đã trả lờithay vìe1, e2. |
| Đặt tên trạng thái một cách rõ ràng | TránhTrạng thái1, Trạng thái2. Sử dụngĐang gọi, Đang reo chuông, Đã kết nối. |
| Tài liệu các giả định | Ví dụ: “Hết thời gian sau 30 giây không hoạt động” cần được ghi chú trong phần chú thích. |
💻 Tạo mã: PlantUML & Mermaid
Dưới đây làcác khối mã sẵn sàng sử dụngđể tạo sơ đồ này theo định dạng bạn mong muốn.
✅ Mã PlantUML
@startuml
[*] --> Idle
Idle --> DialTone : onHook
DialTone --> Dialing : digit(n)
Dialing --> Dialing : digit(n) ' Chuyển tiếp tự thâ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 "Lỗi" as ErrorState {
state "BusyTone" as BusyTone
state "FastBusyTone" as FastBusyTone
state "Thông điệp ghi âm" as RecordedMessage
}
' Hành động nội bộ
Idle : entry / Chờ ngắt kết nối
DialTone : entry / Phát âm thanh gọi
Dialing : entry / Thu thập các chữ số
Connecting : entry / Chuyển cuộc gọi
Ringing : entry / Gọi điện thoại từ xa
Connected : entry / Thiết lập phiên gọi
Disconnected : entry / Kết thúc phiên
@enduml 📥 Cách sử dụng: Dán vào PlantUML Trực tuyến hoặc tiện ích cho IDE của bạn.
✅ Mã Mermaid

stateDiagram-v2
[*] --> Idle
Idle --> DialTone : onHook
DialTone --> Dialing : digit(n)
Dialing --> Dialing : digit(n) ' Chuyển tiếp tự thâ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
Phát âm thanh bận tiêu chuẩn
end note
note right of FastBusyTone
Phát âm thanh bận nhanh (mạng quá tải)
end note
note right of RecordedMessage
Phát thông điệp ghi âm: "Số điện thoại không hoạt động."
end note
note right of Timeout
Thử gọi bị hủy sau 40 giây
end note
📥 Cách sử dụng: Dán vào Trình chỉnh sửa Mermaid Trực tuyến hoặc các công cụ Markdown được hỗ trợ (VS Code, Obsidian, v.v.).
📚 Tóm tắt và suy nghĩ cuối cùng
Đây là Hệ thống điều khiển cuộc gọi điện thoại máy trạng thái là một ví dụ thực tế về cách UML có thể mô hình hóa các hệ thống phức tạp, dựa trên sự kiện với độ tin cậy cao.
✅ Điều gì làm cho sơ đồ này hiệu quả:
- Rõ ràng đường đi chính với luồng logic rõ ràng.
- Xử lý lỗi toàn diện xử lý lỗi.
- Sử dụng chuyển tiếp tự thân, trạng thái hợp thành, và các điều kiện.
- Sự rõ ràng trực quan nhờ sự nhóm lại và ghi chú.
🛠️ Khi nào nên sử dụng mẫu này:
- Hệ thống điện thoại
- Điều khiển thiết bị IoT
- Quản lý phiên người dùng
- Động cơ quy trình làm việc
- Hệ thống nhúng với logic trạng thái hữu hạn
📝 Muốn mở rộng thêm?
Xem xét thêm:
- Ghi âm cuộc gọi trạng thái (với
bắt đầuGhi âm,dừngGhi âmsự kiện) - Chuyển cuộc gọi logic (điều hướng có điều kiện)
- Chờ cuộc gọi hỗ trợ (trạng thái song song)
- Chuyển cuộc gọi là trạng thái con của
Đã kết nối - Lịch sử trạng thái (lịch sử nông/lịch sử sâu) để tái nhập sau khi bị gián đoạn
📌 Đề xuất cuối cùng
Luôn mô hình hóa cả hai hành trình thành công và thất bại.
Một máy trạng thái chỉ xử lý các “đường đi thuận lợi” là chưa hoàn chỉnh và dễ gặp lỗi trong môi trường sản xuất.
Sử dụng hướng dẫn này như một mẫu để mô hình hóa bất kỳ hệ thống thời gian thực nào mà chuyển đổi trạng thái, sự kiện, và khả năng chịu lỗi là điều quan trọng.
✅ Sẵn sàng tạo, trực quan hóa hoặc mở rộng?
👉 Sao chép mã PlantUML hoặc Mermaid bên trên và tích hợp nó vào tài liệu, sơ đồ kiến trúc hoặc tài liệu thiết kế hệ thống của bạn.
Hãy cho tôi biết nếu bạn muốn một phiên bản PDF, sơ đồ tương tác, hoặc tích hợp vào mô hình hệ thống lớn hơn (ví dụ: với các thành phần hoặc sơ đồ tuần tự)!
📘 “Những hệ thống tốt nhất không chỉ đúng mà còn dự đoán trước thất bại.”
— Thiết kế với máy trạng thái UML










