Hướng dẫn toàn diện: Mô hình hóa một Hệ thống điều khiển cuộc gọi điện thoại bằng Sơ đồ Máy trạng thái UML

🎯 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ạisử 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 đổi 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 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 thỏa 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ưonHookvalidNumber).
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 ở trongĐang gọ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ậnTone bận nhanhTin 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ụngsự 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à tác dụng phụ.


🔄 Chu kỳ sống cuộc gọi đi: 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 chờ (điện thoại đang trên giá đỡ)

  • Sự kiện: điện thoại đang trên giá đỡ (người dùng nhấc điện thoại lên)

  • Chuyển tiếp: điện thoại đang trên giá đỡ → Tín hiệu chờ

  • Hành động: Tạo tín hiệu chờ; 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 vòng đời cuộc gọi.

🔹 Tín hiệu chờ → Đ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ọi chế độ.

🔹 Chuyển tiếp tự thân: Đang gọi → Đang gọi (chữ số(n))

  • Sự kiện: chữ số(n) (nhập nhiều chữ số liên tiế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ọi trạ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ố điện thoại 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: numberBusy → Tín hiệu bận

  • Hành động: Phát tín hiệu bận; thông báo cho người dùng biết đường dây đang bận.

🔹 Đang kết nối → Tín hiệu bận nhanh (trunkBusy)

  • Sự kiện: trunkBusy

  • Chuyển tiếp: trunkBusy → Tín hiệu bận nhanh

  • Hành động: Phát tín hiệu 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ế thời gian chờ và cảnh báo

🔹 Đang quay số → Cảnh báo (hết thời gian)

  • Sự kiện: hết thời gian sau 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 ngắt kết nối.

🔹 Cảnh báo → Hết thời gian (hết thời gian)

  • Sự kiện: hết thời gian lần nữa sau 10 giây

  • Chuyển tiếp: timeout → Thời gian chờ hết

  • Hành động: Hủy bỏ cuộc gọi; quay lại Ngưng hoạt động.

⏱️ Logic thời gian chờ 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 (nhấc 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:

    1. Người dùng ngắt kết nối: nhấc máy → Ngắt kết nối

    2. Đối phương treo máy: calledPhoneHangsUp → Ngắt kết nối

🔄 Cả hai chuyển tiếp đều dẫn đến Ngắt kết nối trước khi đạt đến Trạ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 hạnh phúc Giữ luồng chính (Ngưng → Tín hiệu bấm số → Đang bấm số → Đang kết nối → Đang reo → Đã kết nối) như một đường thẳng đứng hoặc ngang sạch sẽ.
Rẽ ra ngoài cho các ngoại lệ Đặt các trạng thái lỗi (Tín hiệu bận, Tín hiệu bận nhanh, 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ê BusyToneFastBusyTone, 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ề DialTone hoặc Idle sau 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ệ (tăng cường 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ế có thể thất bại. Thiết kế cho số không hợp lệhết thời gian chờkênh bậnđảm bảo độ tin cậy.
Sử dụng biểu thức hành động Bao gồm / logCallAttempt() hoặc / playTone() để hiển thị 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ìe1e2.
Đặt tên trạng thái một cách rõ ràng TránhTrạng thái1Trạng thái2. Sử dụngĐang gọiĐang reoĐã 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

[*] –> Đang chờ
Đang chờ –> Tín hiệu gọi : treo máy
Tín hiệu gọi –> Đang gọi : nhấn số(n)
Đang gọi –> Đang gọi : nhấn số(n) ‘ Chuyển tiếp tự thân
Đang gọi –> Đang kết nối : số hợp lệ
Đang gọi –> Tin nhắn đã ghi : số không hợp lệ
Đang gọi –> Cảnh báo : hết thời gian
Cảnh báo –> Hết thời gian : hết thời gian
Đang kết nối –> Đang reo chuông : đã định tuyến
Đang kết nối –> Tín hiệu bận : số bận
Đang kết nối –> Tín hiệu bận nhanh : đường trục bận
Đang reo chuông –> Đã kết nối : điện thoại người gọi đã trả lời
Đã kết nối –> Ngắt kết nối : treo máy
Đã kết nối –> Ngắt kết nối : điện thoại người gọi treo máy
Ngắt kết nối –> [*] : dọn dẹp

trạng thái “Lỗi” là ErrorState {
trạng thái “Tín hiệu bận” là BusyTone
trạng thái “Tín hiệu bận nhanh” là FastBusyTone
trạng thái “Tin nhắn đã ghi” là RecordedMessage
}

‘ Các hành động nội bộ
Ngưng hoạt động : nhập / Chờ treo máy
Tín hiệu bấm số : nhập / Phát tín hiệu bấm số
Đang gọi : nhập / Thu thập các chữ số
Đang kết nối : nhập / Định tuyến cuộc gọi
Đang reo chuông : nhập / Gọi chuông điện thoại xa
Đã kết nối : nhập / Thiết lập phiên gọi
Ngắt kết nối : nhập / Kết thúc phiên

@enduml

📥 Cách sử dụng: Dán vào PlantUML Live 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 báo ghi âm: "Số điện thoại không hoạt động."
    end note

    note right of Timeout
        Cuộc 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ộtví 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ì khiến 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ântrạng thái hợp thành, và điều kiện bảo vệ.

  • Độ rõ ràng trực quan nhờ sắp xếp nhóm 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

  • Các bộ động lực công 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 đầu ghi âmdừng ghi âm sự kiện)

  • Chuyển cuộc gọi logic (điều hướng đ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/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ả các đường đi 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 nơi chuyển đổi trạng tháisự kiện, và khả năng chịu lỗi 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 mã phía 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 PDFsơ đồ 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ỉ chính xác—chúng dự đoán trước sự thất bại.”
— Thiết kế với máy trạng thái UML