TÓM TẮT
- 1 1. Giới thiệu chung về sơ đồ lớp
- 2 2. Bước chuẩn bị trước khi vẽ sơ đồ lớp
- 3 3. Các thành phần cơ bản của sơ đồ lớp
- 4 4. Quy trình vẽ sơ đồ lớp chi tiết
- 5 5. Ví dụ thực tế: Vẽ sơ đồ lớp cho một hệ thống bán hàng trực tuyến
- 6 6. Các nguyên tắc thiết kế nâng cao trong sơ đồ lớp
- 7 7. Thực hành vẽ sơ đồ lớp với PlantUML
- 8 8. Lưu ý khi đưa sơ đồ lớp vào tài liệu dự án
- 9 9. Kiểm tra chất lượng sơ đồ lớp bằng checklist
- 10 10. Tổng kết
1. Giới thiệu chung về sơ đồ lớp
Sơ đồ lớp (Class Diagram) là một trong những biểu đồ quan trọng nhất của UML (Unified Modeling Language). Nó mô tả cấu trúc tĩnh của hệ thống bằng cách thể hiện các lớp, các thuộc tính, các phương thức và mối quan hệ giữa chúng. Khi chúng ta thực hiện phân tích và thiết kế phần mềm, việc vẽ sơ đồ lớp giúp:
- Hiểu rõ kiến trúc: Nắm bắt được các thành phần chính và cách chúng tương tác.
- Giao tiếp hiệu quả: Đưa ra một ngôn ngữ chung cho các thành viên trong nhóm, từ nhà phân tích, nhà thiết kế, tới lập trình viên.
- Kiểm tra tính đầy đủ: Xác định xem các yêu cầu nghiệp vụ đã được hiện thực hóa trong mô hình hay chưa.
- Hỗ trợ lập trình hướng đối tượng: Khi mô hình đã hoàn thiện, việc chuyển sang code sẽ trở nên suôn sẻ hơn.
Trong bài viết này, chúng ta sẽ đi sâu vào cách vẽ sơ đồ lớp một cách chi tiết, từ việc chuẩn bị, lựa chọn công cụ, xác định các thành phần chính, tới việc biểu diễn các mối quan hệ phức tạp. Nội dung được chia thành các phần rõ ràng, mỗi phần sẽ cung cấp ví dụ thực tế và mẹo thực hành để bạn có thể áp dụng ngay vào dự án của mình.
2. Bước chuẩn bị trước khi vẽ sơ đồ lớp
2.1. Thu thập và phân tích yêu cầu
Trước khi bắt tay vào vẽ sơ đồ lớp, bạn cần nắm vững các yêu cầu chức năng và phi chức năng của hệ thống. Các tài liệu quan trọng bao gồm:
| Tài liệu | Mô tả |
|---|---|
| Use Case Diagram | Xác định các tác nhân và các trường hợp sử dụng, giúp bạn biết hệ thống cần cung cấp những chức năng gì. |
| Yêu cầu nghiệp vụ (Business Requirements) | Mô tả quy trình, quy tắc nghiệp vụ, các đối tượng quan trọng trong lĩnh vực. |
| Biểu đồ tuần tự (Sequence Diagram) | Cho thấy tương tác thời gian giữa các đối tượng, hỗ trợ xác định các phương thức cần có. |
| Biểu đồ trạng thái (State Diagram) | Nếu có các đối tượng có trạng thái phức tạp, biểu đồ này giúp bạn xác định thuộc tính trạng thái. |
2.2. Xác định phạm vi (Scope) của sơ đồ
Một dự án lớn có thể có nhiều sơ đồ lớp (các mô-đun, các tầng, hoặc các miền nghiệp vụ). Bạn cần quyết định:

Có thể bạn quan tâm: Cách Vẽ Sơ Đồ Cây: Hướng Dẫn Chi Tiết Từ Đầu Đến Cuối
- Sơ đồ lớp cấp cao (High‑level Class Diagram): Chỉ hiển thị các lớp chính, các package và mối quan hệ tổng quan.
- Sơ đồ lớp chi tiết (Detailed Class Diagram): Bao gồm các thuộc tính, phương thức, và các chi tiết kỹ thuật như kiểu dữ liệu, phạm vi truy cập (public, private, protected).
2.3. Lựa chọn công cụ vẽ
Có rất nhiều công cụ hỗ trợ vẽ UML, mỗi công cụ có ưu nhược điểm riêng:
| Công cụ | Miễn phí / Trả phí | Đặc điểm nổi bật |
|---|---|---|
| StarUML | Trả phí (có bản trial) | Giao diện hiện đại, hỗ trợ nhiều loại biểu đồ. |
| PlantUML | Miễn phí (open‑source) | Viết mô tả bằng ngôn ngữ text, dễ tích hợp vào CI/CD. |
| Visual Paradigm | Miễn phí (Community) & Trả phí | Tích hợp mạnh mẽ với IDE, có tính năng reverse engineering. |
| Lucidchart | Trả phí (có bản trial) | Dễ dùng, làm việc nhóm trực tuyến. |
| draw.io (diagrams.net) | Miễn phí | Đơn giản, tích hợp Google Drive. |
Nếu bạn làm việc trong môi trường Agile, PlantUML là lựa chọn tốt vì bạn có thể viết sơ đồ trong file .md hoặc .puml và tự động sinh ra hình ảnh trong repo.
3. Các thành phần cơ bản của sơ đồ lớp
3.1. Lớp (Class)
Mỗi lớp được biểu diễn bằng một hộp chia thành ba phần:
- Tên lớp (được viết ở giữa, thường in đậm và có thể có stereotype như
<<interface>>). - Thuộc tính (Attributes) – liệt kê các biến thành viên.
- Phương thức (Operations) – liệt kê các hàm thành viên.
Quy tắc đặt tên và ký hiệu
| Thành phần | Quy tắc đặt tên | Ký hiệu truy cập |
|---|---|---|
| Thuộc tính | tênThuộcTính : KiểuDữLiệu |
+ (public), - (private), # (protected), ~ (package) |
| Phương thức | tênPhươngThức(đốiSố) : KiểuTrảVề |
Cũng dùng các ký hiệu trên. |
Ví dụ:
+---------------------------+
| Customer |
+---------------------------+
| -customerId : int |
| -name : String |
| -email : String |
+---------------------------+
| +getId() : int |
| +setName(name : String) |
| +placeOrder(o : Order) |
+---------------------------+
3.2. Giao diện (Interface)
Giao diện là một lớp đặc biệt chỉ chứa phương thức trừu tượng (không có phần cài đặt). Khi vẽ, bạn thường đặt stereotype <<interface>> phía trên tên.
+---------------------+
| <<interface>> |
| Payable |
+---------------------+
| +pay(amount : double) : void |
+---------------------+
3.3. Gói (Package)
Package dùng để đóng gói các lớp có liên quan. Khi vẽ, bạn vẽ một hình chữ nhật lớn, bên trong là các lớp thuộc gói. Gói giúp giảm độ phức tạp khi sơ đồ có nhiều lớp.

Có thể bạn quan tâm: Cách Vẽ Robot Đơn Giản: Hướng Dẫn Từng Bước Dành Cho Người Mới Bắt Đầu
3.4. Các loại quan hệ
| Loại quan hệ | Ký hiệu | Mô tả |
|---|---|---|
| Association | Đường thẳng | Mối quan hệ “có” (has‑a). Có thể có nhãn role và multiplicity (1, 0.., 1..). |
| Aggregation | Đường thẳng + hình thoi rỗng | “Có” yếu, phần tử có thể tồn tại độc lập. |
| Composition | Đường thẳng + hình thoi đen | “Có” mạnh, phần tử không tồn tại riêng (được tạo và hủy cùng chủ thể). |
| Generalization | Đường thẳng mũi tên rỗng (triangular) | Kế thừa (inheritance). |
| Realization | Đường thẳng nét đứt + mũi tên rỗng | Lớp thực thi giao diện. |
| Dependency | Đường thẳng nét đứt | Một lớp phụ thuộc vào lớp khác (sử dụng tạm thời). |
Ví dụ về mối quan hệ:
Customer "1" <>-- "0.." Order
Order "1" -- "1.." OrderItem
Payment "1" ..> "1" Payable (realization)
4. Quy trình vẽ sơ đồ lớp chi tiết
4.1. Bước 1: Xác định các lớp chính
Dựa vào Use Case Diagram và Yêu cầu nghiệp vụ, liệt kê các đối tượng (entity) quan trọng. Thông thường, các đối tượng trong cơ sở dữ liệu (tables) hoặc đối tượng nghiệp vụ sẽ trở thành lớp.
Kỹ thuật “Noun Extraction”: Đọc tài liệu yêu cầu, gạch dưới mọi danh từ (customer, order, invoice, payment…). Sau đó, loại bỏ các danh từ không cần thiết (system, manager) và nhóm lại thành các lớp.
4.2. Bước 2: Xác định thuộc tính và phương thức
- Thuộc tính: Dựa trên các trường dữ liệu (field) trong bảng hoặc thông tin cần lưu trữ.
- Phương thức: Dựa trên các hành động (verb) liên quan tới lớp. Ví dụ, “place order” → phương thức
placeOrder()trong lớpCustomer.
Mẹo: Không nên đưa tất cả các thuộc tính vào sơ đồ lớp chi tiết. Chỉ đưa những thuộc tính quan trọng đối với kiến trúc, các thuộc tính phụ có thể để trong tài liệu thiết kế chi tiết.

Có thể bạn quan tâm: Cách Vẽ Quả Dưa Hấu: Hướng Dẫn Từng Bước Đầy Đủ Cho Người Mới Bắt Đầu
4.3. Bước 3: Xác định mối quan hệ
- Association: Khi một lớp cần tham chiếu tới lớp khác. Ví dụ,
Ordercó mộtCustomer. - Aggregation / Composition: Khi một lớp chứa danh sách các đối tượng khác. Quyết định aggregation hay composition dựa vào vòng đời:
- Nếu đối tượng con có thể tồn tại độc lập → Aggregation.
- Nếu đối tượng con không tồn tại nếu không có đối tượng cha → Composition.
- Generalization: Khi có quan hệ “là một” (is‑a). Ví dụ,
Employeelà mộtPerson. - Realization: Khi một lớp thực thi một giao diện. Ví dụ,
CreditCardPaymentthực thiPayable.
4.4. Bước 4: Thêm multiplicity (số lượng)
Multiplicity cho biết số lượng đối tượng ở mỗi đầu của quan hệ:
| Multiplicity | Ý nghĩa |
|---|---|
1 |
Một đối tượng duy nhất |
0..1 |
Không hoặc một |
hoặc 0.. |
Không giới hạn |
1.. |
Ít nhất một |
n |
Chính xác n đối tượng |
Ví dụ: Một Customer có nhiều Order → Customer "1" <>-- "0.." Order.
4.5. Bước 5: Đánh dấu visibility (phạm vi truy cập)
Sử dụng ký hiệu +, -, #, ~ để chỉ ra public, private, protected, package. Điều này giúp lập trình viên hiểu rõ mức độ truy cập.
4.6. Bước 6: Kiểm tra tính nhất quán và hoàn thiện
- Kiểm tra vòng lặp: Đảm bảo không có vòng lặp vô nghĩa (ví dụ:
AcontainsBvàBcontainsAmà không có quan hệ aggregation/composition hợp lý). - Kiểm tra tên: Tên lớp, thuộc tính, phương thức nên dùng CamelCase (Java) hoặc PascalCase (C#) và phản ánh đúng nghiệp vụ.
- Đánh giá mức độ chi tiết: Đối với tài liệu thiết kế, sơ đồ lớp chi tiết không nên quá dài (tránh hơn 30‑40 lớp trong một sơ đồ). Nếu quá, hãy chia thành các package hoặc sub‑diagrams.
5. Ví dụ thực tế: Vẽ sơ đồ lớp cho một hệ thống bán hàng trực tuyến
5.1. Phân tích yêu cầu
- Các tác nhân: Khách hàng, Quản trị viên, Hệ thống thanh toán.
- Các chức năng chính:
- Đăng ký / đăng nhập.
- Duyệt danh mục sản phẩm.
- Thêm sản phẩm vào giỏ hàng.
- Tạo đơn hàng.
- Thanh toán (credit card, PayPal, COD).
- Quản lý sản phẩm, đơn hàng (admin).
5.2. Xác định lớp chính
| Lớp | Mô tả |
|---|---|
User |
Thông tin chung của người dùng (username, password). |
Customer |
Kế thừa User, có thông tin cá nhân, địa chỉ. |
Admin |
Kế thừa User, có quyền quản trị. |
Product |
Thông tin sản phẩm (id, name, price, stock). |
Category |
Nhóm sản phẩm. |
Cart |
Giỏ hàng của khách, chứa CartItem. |
CartItem |
Mỗi mục trong giỏ (product, quantity). |
Order |
Đơn hàng, chứa OrderItem. |
OrderItem |
Chi tiết từng mặt hàng trong đơn. |
Payment (abstract) |
Lớp trừu tượng cho các phương thức thanh toán. |
CreditCardPayment |
Thực thi Payment. |
PayPalPayment |
Thực thi Payment. |
CODPayment |
Thực thi Payment. |
Invoice |
Hóa đơn, liên quan tới Order. |
5.3. Vẽ sơ đồ lớp (chi tiết)

Có thể bạn quan tâm: Cách Vẽ Pokémon Hệ Rồng: Hướng Dẫn Chi Tiết Từ Cơ Bản Đến Nâng Cao
+------------------------+ +------------------------+
| <<abstract>> Payment |<>------- | CreditCardPayment |
+------------------------+ +------------------------+
| -amount : double | | +process() : boolean |
| -date : Date | +------------------------+
+------------------------+ ^ | +process() : boolean | | +------------------------+ | ^ | | | +------------------------+ +------------------------+
| PayPalPayment | | CODPayment |
+------------------------+ +------------------------+
| +process() : boolean | | +process() : boolean |
+------------------------+ +------------------------+ +------------------------+ +------------------------+
| User |<|----------| Admin |
+------------------------+ Generalization +------------------------+
| -userId : int | | +manageProduct() : void |
| -username : String | | +viewReports() : void |
| -password : String | +------------------------+
+------------------------+
| +login() : boolean |
| +logout() : void |
+------------------------+ User <|-- Customer
+------------------------+ +------------------------+
| Customer | | Category |
+------------------------+ +------------------------+
| -customerId : int | | -categoryId : int |
| -name : String | | -name : String |
| -email : String | +------------------------+
+------------------------+ | +addProduct(p:Product) |
| +placeOrder(o:Order) | +------------------------+
| +addToCart(i:CartItem) |
+------------------------+ Customer "1" <>-- "1" Cart
Cart "1" -- "0.." CartItem
CartItem -- Product CartItem -- Product
Order "1" -- "1.." OrderItem
OrderItem -- Product
Order "1" ..> Payment
Order "1" --> Invoice
Product -- Category
- Giải thích:
Paymentlà lớp trừu tượng, các lớp con (CreditCardPayment,PayPalPayment,CODPayment) thực thi phương thứcprocess().Customerkế thừaUser, có quan hệ composition vớiCart.Cartcomposition vớiCartItem; mỗiCartItemtham chiếu tới mộtProduct.Ordercomposition vớiOrderItemvà phụ thuộc (dependency) vàoPaymentđể thực hiện thanh toán.Productaggregation vớiCategory(một sản phẩm thuộc một danh mục, nhưng danh mục vẫn tồn tại khi sản phẩm bị xóa).
5.4. Kiểm tra và tinh chỉnh
- Multiplicity: Đảm bảo rằng một
Customerchỉ có mộtCart("1"), nhưng mộtCartcó thể chứa nhiềuCartItem("0.."). - Visibility: Thuộc tính nhạy cảm (
password) được đánh dấu-(private), các phương thức công cộng (login,placeOrder) được đánh dấu+. - Package: Đối với dự án lớn, chúng ta có thể nhóm các lớp vào các package:
com.ecommerce.user→User,Customer,Admin.com.ecommerce.product→Product,Category.com.ecommerce.order→Cart,CartItem,Order,OrderItem,Invoice.com.ecommerce.payment→Payment, các lớp con.
6. Các nguyên tắc thiết kế nâng cao trong sơ đồ lớp
6.1. Nguyên tắc SOLID
- Single Responsibility Principle (SRP): Mỗi lớp chỉ nên có một trách nhiệm duy nhất. Ví dụ, không nên để lớp
Orderthực hiện cả việc tính thuế và gửi email xác nhận; tạo các lớpTaxCalculator,EmailService. - Open/Closed Principle (OCP): Lớp nên mở để mở rộng, đóng để sửa đổi. Việc sử dụng
Paymentabstract class và các subclass là một ví dụ điển hình. - Liskov Substitution Principle (LSP): Các lớp con phải có thể thay thế lớp cha mà không làm hỏng chương trình. Khi thiết kế
CreditCardPayment, đảm bảo nó thực hiện đầy đủ hợp đồngprocess(). - Interface Segregation Principle (ISP): Không ép buộc lớp phải triển khai các phương thức không cần. Thay vì một giao diện
PaymentServicechứaprocessCreditCard,processPayPal,processCOD, chúng ta chia thành các giao diện riêng. - Dependency Inversion Principle (DIP): Các module cấp cao không nên phụ thuộc vào module cấp thấp mà nên phụ thuộc vào abstraction. Khi
Orderphụ thuộc vàoPayment(abstraction) chứ không phải trực tiếp vàoCreditCardPayment.
6.2. Design Patterns thường gặp trong sơ đồ lớp
| Pattern | Mô tả ngắn | Áp dụng trong sơ đồ lớp |
|---|---|---|
| Factory Method | Tạo đối tượng mà không xác định lớp cụ thể. | PaymentFactory để tạo đối tượng Payment dựa trên loại thanh toán. |
| Strategy | Định nghĩa một họ thuật toán, đóng gói chúng và làm cho chúng có thể hoán đổi. | Các lớp Payment là các strategy cho việc thanh toán. |
| Observer | Khi một đối tượng thay đổi, các đối tượng đăng ký sẽ được thông báo. | Khi Order thay đổi trạng thái, EmailService (observer) gửi email. |
| Decorator | Thêm hành vi động cho đối tượng. | GiftWrapDecorator cho OrderItem. |
| Composite | Trao đổi đối tượng đơn lẻ và tập hợp như nhau. | Cart và CartItem (có thể áp dụng Composite nếu muốn xử lý giỏ hàng như một đối tượng duy nhất). |
6.3. Tối ưu hoá mối quan hệ
- Tránh quá nhiều quan hệ “Association”: Nếu một lớp chỉ cần một thuộc tính ID để liên kết, không cần vẽ association chi tiết, chỉ ghi chú “FK”.
- Sử dụng Interface để giảm coupling: Thay vì
Orderphụ thuộc trực tiếp vàoCreditCardPayment, nó phụ thuộc vàoPaymentinterface. - Sử dụng Dependency Injection (DI): Khi mô hình được chuyển sang code, các phụ thuộc sẽ được tiêm (inject) vào thông qua constructor hoặc setter, giảm việc khởi tạo trực tiếp.
7. Thực hành vẽ sơ đồ lớp với PlantUML
Nếu bạn muốn tự động sinh sơ đồ từ mã text, PlantUML là công cụ lý tưởng. Dưới đây là ví dụ code cho sơ đồ lớp ở phần 5:

@startuml
' Định nghĩa các interface và abstract class
abstract class Payment { -amount : double -date : Date +process() : boolean
}
class CreditCardPayment { +process() : boolean
}
class PayPalPayment { +process() : boolean
}
class CODPayment { +process() : boolean
}
Payment <|-- CreditCardPayment
Payment <|-- PayPalPayment
Payment <|-- CODPayment ' Định nghĩa User hierarchy
class User { -userId : int -username : String -password : String +login() : boolean +logout() : void
}
class Customer { -customerId : int -name : String -email : String +placeOrder(o:Order) : void +addToCart(i:CartItem) : void
}
class Admin { +manageProduct() : void +viewReports() : void
}
User <|-- Customer
User <|-- Admin ' Các lớp nghiệp vụ
class Product { -productId : int -name : String -price : double -stock : int
}
class Category { -categoryId : int -name : String
}
class Cart {
}
class CartItem {
}
class Order { -orderId : int -date : Date -status : String
}
class OrderItem {
}
class Invoice {
}
' Quan hệ
Customer "1" <>-- "1" Cart
Cart "1" -- "0.." CartItem
CartItem -- Product
Order "1" -- "1.." OrderItem
OrderItem -- Product
Order "1" ..> Payment
Order "1" --> Invoice
Product -- Category
@enduml
Sau khi lưu vào file ecommerce.puml, chạy lệnh:
plantuml ecommerce.puml
Sẽ tạo ra file ecommerce.png chứa sơ đồ lớp. Việc này giúp đồng bộ hóa tài liệu và tự động cập nhật khi thay đổi mô hình.
8. Lưu ý khi đưa sơ đồ lớp vào tài liệu dự án
- Định dạng: Sử dụng PNG hoặc SVG để đảm bảo độ nét khi in và hiển thị trên web.
- Phiên bản: Đánh số phiên bản cho mỗi sơ đồ (ví dụ:
ClassDiagram_v1.2.pdf). Khi có thay đổi, cập nhật số phiên bản và ghi chú thay đổi (Change Log). - Mô tả ngắn gọn: Mỗi sơ đồ nên có một đoạn mô tả (khoảng 2‑3 câu) giải thích mục đích và phạm vi.
- Liên kết tới tài liệu khác: Đặt hyperlink từ lớp tới tài liệu chi tiết (ví dụ:
Customer→CustomerSpecification.docx). - Đánh dấu “TODO”: Nếu một lớp chưa hoàn thiện, dùng comment
// TODO: add attributestrong PlantUML hoặc chú thích trong hình.
9. Kiểm tra chất lượng sơ đồ lớp bằng checklist
| Tiêu chí | Kiểm tra |
|---|---|
| Tên lớp | Đúng chuẩn, không trùng, phản ánh nghiệp vụ. |
| Thuộc tính | Đủ, đúng kiểu, có visibility. |
| Phương thức | Đủ, có tham số, trả về giá trị, có visibility. |
| Quan hệ | Đúng loại (association, aggregation, composition, generalization, realization, dependency). |
| Multiplicity | Được đặt ở cả hai đầu của quan hệ, logic với nghiệp vụ. |
| Package | Các lớp được nhóm hợp lý, giảm độ phức tạp. |
| Sự nhất quán | Không có vòng lặp vô nghĩa, không có lớp thừa. |
| Tuân thủ SOLID | Đánh giá nhanh các nguyên tắc SOLID. |
| Định dạng | Đúng định dạng file, có chú thích phiên bản. |
Nếu mọi mục trong checklist đều “đạt”, sơ đồ lớp của bạn đã sẵn sàng cho phát triển và đánh giá.
10. Tổng kết
Việc vẽ sơ đồ lớp không chỉ là một nhiệm vụ kỹ thuật mà còn là một nghệ thuật truyền đạt kiến trúc phần mềm. Bằng cách:
- Thu thập yêu cầu kỹ lưỡng,
- Xác định lớp, thuộc tính, phương thức một cách có hệ thống,
- Biểu diễn đúng loại quan hệ và multiplicity,
- Áp dụng các nguyên tắc thiết kế (SOLID, Design Patterns),
- Sử dụng công cụ phù hợp (PlantUML, StarUML, v.v.) và đảm bảo tính nhất quán,
bạn sẽ tạo ra một sơ đồ lớp đầy đủ, dễ hiểu và dễ bảo trì. Điều này không chỉ giúp đội ngũ phát triển nhanh chóng chuyển từ thiết kế sang code mà còn giảm thiểu rủi ro lỗi thiết kế, tăng tính mở rộng và độ tin cậy của hệ thống.
Hy vọng bài viết chi tiết trên đã cung cấp cho bạn một hướng dẫn toàn diện để vẽ sơ đồ lớp chuẩn, từ khâu chuẩn bị đến kiểm tra cuối cùng. Hãy áp dụng ngay vào dự án hiện tại của bạn, và đừng quên cập nhật sơ đồ mỗi khi có thay đổi kiến trúc – vì một sơ đồ lớp luôn sống động chính là chìa khóa của một dự án phần mềm thành công.
