
Trong thế giới yêu cầu phần mềm và mô hình hóa hệ thống,UML (Ngôn ngữ mô hình hóa thống nhất)vẫn là nền tảng cốt lõi để trực quan hóa hành vi hệ thống. Trong số những tính năng mạnh mẽ nhất nhưng thường bị hiểu nhầm nhất là các«include» và «extend» mối quan hệ giữa các trường hợp sử dụng. Những cơ chế này được thiết kế để giảm sự trùng lặp, quản lý sự đa dạng, và nâng cao tính module trong các mô hình trường hợp sử dụng. Tuy nhiên, việc sử dụng sai chúng rất phổ biến—dẫn đến các sơ đồ quá phức tạp, gây nhầm lẫn cho các bên liên quan và làm mất tập trung vào giá trị người dùng.

Bài viết này cung cấp mộthướng dẫn toàn diện, thực tiễn và được hỗ trợ bởi chuyên gia để hiểu, áp dụng và tránh những lỗi phổ biến của «include» và «extend». Chúng ta sẽ khám phá ý nghĩa thực sự của chúng,ý nghĩa thực sự, so sánh chúng song song với nhau, phân tích lý do tại sao chúng rơi vào cùng một cái bẫy như DFDs (phân tích chức năng), và đưa racác thực hành tốt hiện đại cho các đội ngũ năm 2025–2026—đặc biệt là những đội đang làm việc trong môi trường agile, lean hoặc lai ghép.
Định nghĩa:
Mối quan hệ «include» biểu diễn một luồng con bắt buộc, luôn được thực hiệnbắt buộc, luôn được thực hiệnluồng con được tách ra để tái sử dụng trong nhiều trường hợp sử dụng khác nhau.
Luôn được thực hiện: Trường hợp sử dụng được bao gồm sẽ chạy mỗi khi trường hợp sử dụng cơ sở được gọi.
Trường hợp sử dụng cơ sở sẽ không hoàn chỉnh nếu thiếu nó: Không có hành vi được bao gồm, trường hợp sử dụng cơ sở không thể đạt được mục đích của nó.
Hướng phụ thuộc: Mũi tên chỉ hướngtừ cơ sở → được bao gồm.
Ý nghĩa độc lập: Trường hợp sử dụng được bao gồm thườngkhông có ý nghĩa khi riêng lẻ—nó chỉ có ý nghĩa khi là một phần của một quy trình lớn hơn.
So sánh: Giống như mộtgọi hàmhoặcthủ tục controng lập trình—thiết yếu cho routine chính.
“Để thực hiệnĐăng nhập, bạn phảiXác thực Người dùng.”
“Để thực hiệnRút tiền mặt, bạn phải Xác minh mã PIN.”
Đây là các bước bắt buộc. Bạn không thể đăng nhập mà không xác thực. Bạn không thể rút tiền mặt mà không xác minh mã PIN.
Khi một hành vi phổ biến, phức tạp, có thể tái sử dụng xuất hiện trong hai hoặc nhiều hơn trường hợp sử dụng.
Ví dụ:
Xác thực người dùng
Ghi nhật ký kiểm toán
Gửi thông báo
Xác minh định dạng đầu vào
✅ Quy tắc thông thường: Sử dụng «include» chỉ khi hành vi được tái sử dụng là quan trọng, phức tạp, và xuất hiện trong ≥2–3 trường hợp sử dụng.
Định nghĩa:
Mối quan hệ «extend» xác địnhtùy chọn, điều kiện hoặc biến thểhành vi màkết nối vàomột điểm mở rộng cụ thểđiểm mở rộngcủa trường hợp sử dụng cơ bản.
Chạy có điều kiện: Chỉ chạy trong một số điều kiện nhất định.
Trường hợp sử dụng cơ bản hoàn chỉnh khi riêng lẻ: Luồng bình thường hoạt động mà không cần mở rộng.
Hướng phụ thuộc: Mũi tên chỉ hướngtừ mở rộng → cơ bản (ngược lại).
Ý nghĩa độc lập: Trường hợp sử dụng mở rộng làgần như không có ý nghĩa khi riêng lẻ—nó chỉ có ý nghĩatrong bối cảnh.
So sánh: Giống như mộtcái móc, plugin, hoặckhuyên dùng AOP (lập trình hướng khía cạnh)—nó thêm hành vi tại một điểm được xác định.
“Trong khi thực hiện Đặt vé máy bay, bạn có thể muốn Chọn chỗ ngồi ưa thích.”
“Trong khi thực hiện Thanh toán bằng thẻ tín dụng, bạn có thể phải Nhập mã bảo mật 3D.”
Đây là cải tiến tùy chọn—không bắt buộc đối với luồng chính.
Để mô hình hóa các con đường thay thế, trường hợp ngoại lệ, hoặc tính năng tùy chọn.
Khi một trường hợp sử dụng có hành vi khác nhau dựa trên điều kiện (ví dụ: vai trò người dùng, trạng thái hệ thống, sở thích).
Ví dụ:
Áp dụng giảm giá (kế thừa Đặt hàng)
Yêu cầu hoàn tiền (kế thừa Xử lý thanh toán)
Tạo biên lai PDF (kế thừa Hoàn tất giao dịch)
✅ Quy tắc thông thường: Sử dụng «kế thừa» một cách tiết kiệm—chỉ dùng cho sự thay đổi có ý nghĩa với rõ ràng điểm mở rộng.
| Khía cạnh | «bao gồm» | «kế thừa» |
|---|---|---|
| Thực thi | Luôn luôn | Đôi khi / có điều kiện |
| UC cơ bản có hoàn thành độc lập không? | ❌ Không — phụ thuộc vào phần được bao gồm | ✅ Có — hoàn thành mà không cần mở rộng |
| Hướng phụ thuộc | Cơ sở → Bao gồm | Mở rộng → Cơ sở |
| Hướng mũi tên | Chỉ đến trường hợp sử dụng được bao gồm | Chỉ đến trường hợp sử dụng cơ sở |
| Mục tiêu chính | Tái sử dụng các bước bắt buộc, chung | Xử lý các luồng tùy chọn/biến thể |
| So sánh | Gọi hàm / thủ tục con | Hook / tiện ích / lời khuyên AOP |
| Có ý nghĩa độc lập? | Hiếm khi | Gần như không bao giờ |
| Tốt nhất cho | Các vấn đề tái sử dụng, phức tạp, xuyên suốt | Hành vi điều kiện, tùy chọn hoặc thay thế |
Giống như Sơ đồ luồng dữ liệu (DFD) bị ảnh hưởng bởi bẫy phân tích chức năng, sơ đồ trường hợp sử dụng cũng bị dễ mắc phải căn bệnh chết người tương tự: phân tích quá mức.
Các đội tiếp tục chia nhỏ các quy trình thành những bong bóng ngày càng nhỏ hơn.
Các sơ đồ nổ tung thành hàng chục hàm cấp thấp, nhỏ bé.
Cái mục đích ban đầu—gửi giá trị đến người dùng—bị mất.
Cuối cùng trông giống như mã giả hoặc thiết kế thuật toán nội bộ, không phải hành vi người dùng.
Mỗi bước nhỏ đều trở thành một trường hợp sử dụng riêng biệt:
Nhập tên người dùng
Nhập mật khẩu
Nhấn nút Đăng nhập
Xác minh định dạng
Hiển thị thông báo lỗi
«include» được áp dụng thoải mái để phân tách mọi hành động.
Kết quả: Một cấu trúc phân cấp sâu của các trường hợp sử dụng (A → B → C → D…) mà không có mục tiêu rõ ràng của người thực hiện.
Các sơ đồ trở thành khó bảo trì, gây nhầm lẫn, và vô dụng đối với các bên liên quan.
❌ Cờ đỏ: Nếu sơ đồ use case của bạn cóhơn 15–20 use case, hoặc nếuhầu hết các use case cơ bản dài từ 2–4 bước, bạn có thể đang rơi vào bẫy.
| Sai lầm | Giải thích | Cách tránh |
|---|---|---|
| Sử dụng quá nhiều «include» | Xem mọi bước phụ như một use case có thể tái sử dụng. | Chỉ sử dụng «include» choquan trọng, có thể tái sử dụng, chéohành vi (ví dụ: xác thực, ghi log). |
| Sai hướng mũi tên | Vẽ mũi tên «include» ngược chiều (base ← included) hoặc mũi tên «extend» theo chiều thuận. | Nhớ rằng:include = base → included; extend = extending → base. |
| Sử dụng «extend» cho các lựa chọn thay thế | Mô hình hóa các luồng thay thếbên trongmột use case dưới dạng «extend» thay vì sử dụng các lựa chọn văn bản. | Sử dụng luồng thay thế văn bản cho hầu hết các biến thể. Dành «extend» cho mở rộng tùy chọn thực sự. |
| Tạo chuỗi bao gồm | A → B → C → D → E… | Tránh các chuỗi sâu. Nếu bạn cần nhiều bao gồm, hãy cân nhắc tái cấu trúc thành một trường hợp sử dụng có thể tái sử dụng duy nhất. |
| Điểm mở rộng mơ hồ | Thêm các mối quan hệ «extend» mà không có điểm chèn rõ ràng, được đặt tên. | Xác định điểm mở rộng rõ ràng (ví dụ: “Sau khi xác nhận thanh toán”) trong trường hợp sử dụng cơ bản. |
| Sự lộn xộn trong sơ đồ | Quá nhiều trường hợp sử dụng và mối quan hệ → tiếng ồn thị giác. | Giữ sơ đồ nhỏ, tập trung và lấy người dùng làm trung tâm. Sử dụng nhiều sơ đồ cho mỗi hệ thống con. |
| Sự nhầm lẫn của các bên liên quan | Các bên liên quan không chuyên thấy «include/extend» khó hiểu. | Sử dụng cảnh huống văn bản hoặc bản đồ truyện người dùng để rõ ràng. |
| Mô hình hóa ở cấp độ thiết kế | Mô hình hóa kiến trúc nội bộ (ví dụ: “gọi cơ sở dữ liệu”) thay vì mục tiêu người dùng. | Giữ tập trung vào giá trị người dùng—không phải triển khai. |
| Những cuộc tranh luận vô tận | Các đội tranh luận về việc «có nên dùng include hay extend?» thay vì viết các kịch bản. | Sử dụng các nguyên tắc thực tiễn và ưu tiên sự rõ ràng hơn là tính trang trọng. |
Bối cảnh của kỹ thuật yêu cầu đã thay đổi.Các đội Agile, lean và định hướng sản phẩm đang ngày càng rời xa các sơ đồ UML nặng nề để ưu tiên các kỹ thuật nhẹ nhàng, tập trung vào giá trị các kỹ thuật.
❗ Hỏi câu hỏi này trước khi thêm bất kỳ «include» hay «extend» nào:
«Liệu mối quan hệ này có giúp người dùng hiểu được mục tiêu hay chỉ đơn thuần là phân tách hệ thống?»
Chỉ dùng cho các vấn đề xuyên suốt xuất hiện trong nhiều trường hợp sử dụng.
Ví dụ:
Xác thực người dùng
Gửi thông báo email
Ghi sự kiện bảo mật
Áp dụng quy tắc kinh doanh
❌ Tránh:
Nhập tên người dùng,Nhấn Gửi,Xác thực định dạng email
Thay vì:
«extend»: Chọn chỗ ngồi ưu tiên → Đặt chuyến bay
Sử dụng:
Use Case: Đặt chuyến bay
...
Luồng thay thế:
1. Người dùng chọn tùy chọn "Chỗ ngồi ưu tiên".
2. Hệ thống hiển thị bản đồ chỗ ngồi.
3. Người dùng chọn chỗ ngồi.
4. Hệ thống áp dụng ưu tiên chỗ ngồi.
✅ Tại sao? Các luồng văn bản là dễ đọc hơn, linh hoạt hơn, và ít dễ bị lạm dụng.
Một sơ đồ mỗi người diễn viênhoặchệ thống con.
Hạn chế trong5–10 trường hợp sử dụngtrên mỗi sơ đồ.
Sử dụngsơ đồ góihoặcsơ đồ ngữ cảnhđể hiển thị cấu trúc cấp cao.
Nếu bạn đang sử dụng 10+ mối quan hệ «include»/«extend», hãy cân nhắc thay thế sơ đồ bằng:
Mộtbản đồ câu chuyện người dùng
Mộtbảng dựa trên tình huống
Mộtsơ đồ luồng đơn giảnvới các đường đi chính
🔄 Xu hướng hiện đại: Nhiều đội agiletránh hoàn toàn việc sử dụng sơ đồ trường hợp sử dụnghoặc sử dụng chúngchỉ để khám phá cấp cao.
Dành «extend» chotùy chọn, không cốt lõitính năng mà:
Làít được sử dụng
Làphụ thuộc vào ngữ cảnh
Làđộc lậpvới mục tiêu cốt lõi
✅ Ví dụ:
Xử lý thanh toán(cốt lõi)
Áp dụng xác thực 3D Secure(mở rộng) — chỉ khi ngân hàng yêu cầu
❌ Tránh:
Nhập số thẻ→Xác minh thẻ→Xử lý thanh toán(tất cả đều phải là các bước trong cùng một trường hợp sử dụng)
| Quy tắc | Hướng dẫn |
|---|---|
| 1. «include» = Bắt buộc | Chỉ sử dụng chocác bước thiết yếu, có thể tái sử dụngcác bước xuất hiện trong ≥2 trường hợp sử dụng. |
| 2. «extend» = Tùy chọn | Chỉ sử dụng cho điều kiện, biến thể hoặc hiếm gặp hành vi. |
| 3. Trường hợp sử dụng cơ bản phải hoàn chỉnh | «extend»: cơ bản hoạt động độc lập. «include»: cơ bản không hoàn chỉnh nếu thiếu nó. |
| 4. Giữ đơn giản | Nếu một trường hợp sử dụng có ít hơn 4–6 bước sau «include»/«extend», bạn đã phân tích quá mức. |
| 5. Ưu tiên khả năng đọc hiểu | Các tình huống văn bản > sơ đồ phức tạp. |
| 6. Tránh chuỗi | Không có A → B → C → D. Tái cấu trúc thành một trường hợp sử dụng có thể tái sử dụng. |
| 7. Hiểu đối tượng của bạn | Các bên liên quan không quan tâm đến các mũi tên «include»—họ quan tâm đến giá trị. |
| Hỏi: “Đây có phải là mục tiêu người dùng hay một bước nội bộ?” | Nếu nó không phải là mục tiêu của người thực hiện, thì có lẽ nó không thuộc về một trường hợp sử dụng. |
«include» và «extend» là các công cụ mạnh mẽ—không phải quy tắc cứng nhắc. Chúng được thiết kế để:
Giảm sự trùng lặp
Quản lý sự đa dạng
Cải thiện khả năng bảo trì
Nhưng giống như việc phân tích chức năng trong DFDs, chúng trở thành vũ khí nguy hiểm khi được sử dụng quá mức. Nguy hiểm thực sự không nằm ở các mối quan hệ đó—mà là mất phương hướng về mục tiêu của người dùng.
🔥 Nhớ rằng:
Một trường hợp sử dụng không phải là một quy trình kỹ thuật.
Đó là mộtcâu chuyện về điều mà người dùng muốn đạt được—và cách hệ thống hỗ trợ.
Khi còn nghi ngờ,hãy tự hỏi bản thân:
“Liệu người dùng có hiểu điều này mà không cần biết UML không?”
Nếu không, hãy đơn giản hóa.
Nếu có, bạn đang đi đúng hướng.
Especificasi UML (OMG): www.omg.org/spec/UML
Martin Fowler – Mô hình hóa trường hợp sử dụng: Các mẫu phân tích & UML Tóm tắt
Ivar Jacobson – Ưu thế của đối tượng: Công trình nền tảng về trường hợp sử dụng
Mô hình hóa Agile (AM) bởi Scott W. Ambler
Sơ đồ câu chuyện người dùng bởi Jeff Patton – Một lựa chọn hiện đại thay thế cho các sơ đồ phức tạp
Sử dụng «include» để tái sử dụng bắt buộc, «extend» để thay đổi tùy chọn—nhưng chỉ khi thực sự mang lại giá trị. Ngược lại, hãy giữ đơn giản.
Vì cuối cùng,mục tiêu không phải là vẽ các sơ đồ hoàn hảosơ đồ UML—mà là xây dựng các hệ thống mang lại giá trị thực tế cho con người thật.
📌 Ghi chú của tác giả (2025–2026):
Khi các nhóm chuyển sangtập trung vào sản phẩm, dẫn dắt bởi giá trị, vàhợp tácphát triển, vai trò của các sơ đồ UML truyền thống đang thay đổi. «include» và «extend» vẫn hữu ích—nhưngchỉ khi được sử dụng với sự kiểm soát, rõ ràng và mục đích. Hãy để chúng phục vụ người dùng, chứ không phải sơ đồ.