TÓM TẮT
- 1 1. Giới thiệu chung về Class Diagram
- 2 2. Các thành phần cơ bản của Class Diagram
- 3 3. Quy trình vẽ Class Diagram từ A đến Z
- 3.1 3.1. Bước 1: Thu thập yêu cầu và phân tích nghiệp vụ
- 3.2 3.2. Bước 2: Xác định lớp chính và lớp phụ
- 3.3 3.3. Bước 3: Định nghĩa thuộc tính và phương thức
- 3.4 3.4. Bước 4: Xây dựng mối quan hệ
- 3.5 3.5. Bước 5: Kiểm tra tính toàn vẹn và tối ưu hoá
- 3.6 3.6. Bước 6: Ghi chú (Annotations) và stereotype
- 3.7 3.7. Bước 7: Sử dụng công cụ hỗ trợ
- 4 4. Các mẫu (Design Patterns) thường gặp trong Class Diagram
- 5 5. Các khía cạnh nâng cao trong Class Diagram
- 6 6. Thực hành: Vẽ Class Diagram cho một hệ thống quản lý thư viện
- 7 7. Các lỗi thường gặp khi vẽ Class Diagram và cách khắc phục
- 8 8. Lời khuyên thực tiễn khi làm việc nhóm
- 9 9. Kết luận
1. Giới thiệu chung về Class Diagram
Class diagram (sơ đồ lớp) là một trong những mô hình quan trọng nhất trong UML (Unified Modeling Language – Ngôn ngữ mô hình hoá thống nhất). Nó cho phép chúng ta mô tả cấu trúc tĩnh của một hệ thống phần mềm, thể hiện các lớp (class), các thuộc tính (attribute), các phương thức (operation) và mối quan hệ giữa chúng. Khi thiết kế một dự án phần mềm, việc vẽ class diagram giúp:
- Hiểu rõ mô hình dữ liệu: Xác định các thực thể và cách chúng liên kết với nhau.
- Giao tiếp hiệu quả: Đưa ra một ngôn ngữ chung cho các thành viên trong nhóm (phân tích, thiết kế, lập trình, kiểm thử).
- Giảm rủi ro: Phát hiện sớm những lỗi thiết kế, trùng lặp, hoặc quan hệ không hợp lý.
- Hỗ trợ tái sử dụng: Nhận diện các lớp có thể tái dùng hoặc kế thừa.
Trong bài viết này, chúng ta sẽ đi sâu vào quy trình vẽ class diagram, từ việc chuẩn bị, xác định các thành phần cơ bản, cách biểu diễn các mối quan hệ, cho tới các kỹ thuật nâng cao như pattern, generic, và cách sử dụng các công cụ hỗ trợ.
2. Các thành phần cơ bản của Class Diagram
2.1. Lớp (Class)
Mỗi lớp được biểu diễn bằng một hình chữ nhật chia thành ba phần:
- Tên lớp (Class Name) – nằm ở phần trên, viết in đậm, thường là danh từ số ít (ví dụ:
Customer,Order). - Thuộc tính (Attributes) – nằm ở phần giữa, liệt kê các biến thành viên, kèm theo kiểu dữ liệu và phạm vi truy cập (public
+, private-, protected#). - Phương thức (Operations) – nằm ở phần dưới, liệt kê các hàm thành viên, kèm theo kiểu trả về, tham số và phạm vi truy cập.
Ví dụ:
+----------------------+
| Customer |
+----------------------+
| - id: int |
| - name: String |
| - email: String |
+----------------------+
| + getId(): int |
| + setName(name) |
| + sendEmail() |
+----------------------+
2.2. Thuộc tính (Attribute)
- Cú pháp:
visibility name : type multiplicity default - Visibility:
+(public),-(private),#(protected),~(package). - Multiplicity: Thường dùng cho các thuộc tính dạng tập hợp (ví dụ:
0..,1..1).
2.3. Phương thức (Operation)

Có thể bạn quan tâm: Cách Vẽ Chữ Đẹp: Hướng Dẫn Từ Cơ Bản Đến Nâng Cao Cho Người Mới Bắt Đầu
- Cú pháp:
visibility name(par1 : type1, …) : returnType - Có thể có stereotype (góc nhọn) để chỉ mục đích như
<<create>>,<<delete>>.
2.4. Mối quan hệ (Relationships)
| Loại quan hệ | Ký hiệu | Mô tả |
|---|---|---|
| Association | Đường thẳng | Mối quan hệ “có” (has‑a). |
| Aggregation | Đường thẳng + rhombus rỗng | Quan hệ “toàn bộ – phần” yếu (has‑a, phần có thể tồn tại độc lập). |
| Composition | Đường thẳng + rhombus đen | Quan hệ “toàn bộ – phần” mạnh (phần không tồn tại nếu toàn bộ bị xóa). |
| Generalization | Đường thẳng mũi tên tròn | Kế thừa (is‑a). |
| Realization | Đường thẳng mũi tên nét đứt | Thực thi interface. |
| Dependency | Đường nét đứt | Sự phụ thuộc tạm thời (uses‑a). |
3. Quy trình vẽ Class Diagram từ A đến Z
3.1. Bước 1: Thu thập yêu cầu và phân tích nghiệp vụ
- Đọc tài liệu yêu cầu: Xác định các thực thể (entity) quan trọng, các hành động (use cases) và các ràng buộc.
- Sử dụng kỹ thuật “Noun‑Verb”: Tìm danh từ (các đối tượng) và động từ (các hành động) trong mô tả yêu cầu để tạo danh sách sơ bộ các lớp và phương thức.
- Lập danh sách các thuộc tính: Dựa trên các thuộc tính mô tả trong yêu cầu (ví dụ: “Mỗi khách hàng có mã, tên, địa chỉ”).
3.2. Bước 2: Xác định lớp chính và lớp phụ
- Lớp chính (Primary classes): Thường là các thực thể cốt lõi của hệ thống (ví dụ:
User,Product,Invoice). - Lớp phụ (Supporting classes): Các lớp hỗ trợ như
Utility,Validator,Logger. - Lớp trừu tượng (Abstract classes) và Interface: Khi có các nhóm hành vi chung, tách ra thành lớp trừu tượng hoặc interface để giảm sự lặp lại.
3.3. Bước 3: Định nghĩa thuộc tính và phương thức
- Xác định phạm vi truy cập: Các thuộc tính thường là
privatevà được truy cập qua getter/setter. - Phân chia phương thức: Phân loại thành nghiệp vụ (business logic), tiện ích (utility) và các phương thức khởi tạo (constructor).
3.4. Bước 4: Xây dựng mối quan hệ

Có thể bạn quan tâm: Cách Vẽ Chuột Hamster Đầy Đủ Từ Cơ Bản Đến Nâng Cao: Hướng Dẫn Chi Tiết Cho Người Mới Bắt Đầu
- Association:
- Đánh dấu multiplicity (1, 0..1, 0.., 1..).
- Ví dụ:
Order—Customer(một đơn hàng thuộc một khách hàng). - Aggregation vs Composition:
- Nếu phần có thể tồn tại độc lập → Aggregation (
Department—>Employee). - Nếu phần phụ thuộc vào toàn bộ → Composition (
Order—>OrderItem). - Generalization:
- Xác định các lớp con (subclass) và lớp cha (superclass). Ví dụ:
Vehiclelà lớp cha,CarvàMotorbikelà lớp con. - Realization:
- Khi một lớp thực thi một interface, vẽ đường nét đứt mũi tên từ lớp tới interface.
- Dependency:
- Dùng khi một lớp chỉ tạm thời sử dụng lớp khác (ví dụ: một phương thức nhận đối tượng làm tham số).
3.5. Bước 5: Kiểm tra tính toàn vẹn và tối ưu hoá
- Loại bỏ trùng lặp: Nếu nhiều lớp có cùng thuộc tính/phương thức, cân nhắc tạo lớp cha chung.
- Kiểm tra vòng lặp: Tránh các quan hệ vòng (circular dependencies) không cần thiết.
- Đánh giá mức độ chi tiết: Đối với các dự án lớn, có thể tạo nhiều lớp diagram (cấp độ cao, chi tiết) để tránh quá tải thông tin.
3.6. Bước 6: Ghi chú (Annotations) và stereotype
- Stereotype: Thêm
<<entity>>,<<controller>>,<<service>>để phân biệt vai trò. - Ghi chú: Dùng “notes” để giải thích các quyết định thiết kế, ràng buộc nghiệp vụ.
3.7. Bước 7: Sử dụng công cụ hỗ trợ
- Visual Paradigm, StarUML, Enterprise Architect, PlantUML, draw.io, Lucidchart.
- Các công cụ này hỗ trợ kéo thả, tự động tạo code skeleton, và xuất ra các định dạng PNG, SVG, PDF.
4. Các mẫu (Design Patterns) thường gặp trong Class Diagram
4.1. Singleton
- Mục đích: Đảm bảo chỉ có một thể hiện của lớp.
- Biểu diễn: Lớp có constructor private, một static method
getInstance(). - Diagram: Thêm stereotype
<<singleton>>.
4.2. Factory Method
- Mục đích: Tạo đối tượng mà không xác định lớp cụ thể.
- Biểu diễn: Interface
Product, lớpConcreteProduct, và lớpCreatorvới phương thứcfactoryMethod(). - Diagram: Dùng
<<factory>>stereotype, mối quan hệ dependency giữaCreatorvàProduct.
4.3. Observer

Có thể bạn quan tâm: Cách Vẽ Chibi Nữ Đầy Đủ Từ Cơ Bản Đến Nâng Cao: Hướng Dẫn Chi Tiết Cho Người Mới Bắt Đầu
- Mục đích: Khi một đối tượng thay đổi, các đối tượng quan sát được thông báo.
- Biểu diễn: Interface
Observer, lớpSubjectcó danh sáchObserver. - Diagram:
Subjectcó association tớiObserver(0..), vàObservercó dependency tớiSubject.
4.4. Decorator
- Mục đích: Thêm hành vi cho đối tượng hiện có mà không thay đổi lớp gốc.
- Biểu diễn: Interface
Component, lớpConcreteComponent, lớpDecorator(có association tớiComponent), và các lớpConcreteDecorator. - Diagram: Sử dụng Generalization cho
DecoratorvàConcreteDecoratortừComponent.
4.5. Strategy
- Mục đích: Định nghĩa một họ thuật toán, cho phép chúng thay đổi độc lập.
- Biểu diễn: Interface
Strategy, các lớpConcreteStrategyA/B, và lớp Context có association tớiStrategy. - Diagram: Context có thuộc tính
strategy: Strategy, thể hiện bằng association (1).
5. Các khía cạnh nâng cao trong Class Diagram
5.1. Generics (Kiểu tổng quát)
- Java / C#: Khi lớp hoặc phương thức dùng kiểu tổng quát, biểu diễn bằng
<>. - Ví dụ:
class Repository<T>→Repository<T>trong diagram, vớiTlà một parameter.
5.2. Multiple Inheritance (Kế thừa đa dạng)
- C++ cho phép kế thừa nhiều lớp cha, trong diagram ta vẽ nhiều mũi tên Generalization tới các lớp cha.
- Lưu ý: Tránh “diamond problem” bằng cách dùng virtual inheritance hoặc các interface.
5.3. Interface vs Abstract Class

Có thể bạn quan tâm: Cách Vẽ Bùa Yêu: Hướng Dẫn Chi Tiết Từ A Đến Z Để Thu Hút Tình Yêu
- Interface: Chỉ có phương thức trừu tượng, không có thuộc tính (trừ hằng số). Đánh dấu bằng
<<interface>>. - Abstract Class: Có thể chứa thuộc tính, phương thức đã cài đặt, và phương thức trừu tượng. Đánh dấu bằng
<<abstract>>.
5.4. Package Diagram kết hợp
- Khi hệ thống lớn, nhóm các lớp vào package (gói) để giảm độ phức tạp.
- Dependency giữa package thể hiện mối quan hệ cấp độ cao (ví dụ:
servicepackage phụ thuộc vàorepositorypackage).
5.5. Constraint (Ràng buộc)
- UML cho phép thêm OCL (Object Constraint Language) để mô tả ràng buộc phức tạp.
- Ví dụ:
{age > 0}đặt trên thuộc tínhage.
6. Thực hành: Vẽ Class Diagram cho một hệ thống quản lý thư viện
6.1. Yêu cầu cơ bản
- Quản lý Sách (Book), Thành viên (Member), Mượn trả (Loan).
- Mỗi Sách có ISBN, title, author, publisher, copies.
- Thành viên có memberId, name, email, membershipDate.
- Mượn trả ghi lại loanId, borrowDate, dueDate, returnDate.
- Một Thành viên có thể mượn nhiều Sách, mỗi Sách có thể được mượn bởi nhiều Thành viên (nhiều‑nhiều) thông qua Loan.
6.2. Các lớp chính
| Lớp | Thuộc tính | Phương thức |
|---|---|---|
| Book | – isbn: String – title: String – author: String – publisher: String – totalCopies: int – availableCopies: int |
+ isAvailable(): boolean + reduceCopy(): void + increaseCopy(): void |
| Member | – memberId: String – name: String – email: String – membershipDate: Date |
+ canBorrow(): boolean + addLoan(loan: Loan): void |
| Loan | – loanId: String – borrowDate: Date – dueDate: Date – returnDate: Date (nullable) |
+ isOverdue(): boolean + markReturned(date: Date): void |
| Library (Facade) | – books: List – members: List – loans: List |
+ borrowBook(memberId, isbn): Loan + returnBook(loanId): void |
6.3. Mối quan hệ

- Association:
Member "1" — "0.." Loan(một thành viên có 0 hoặc nhiều loan). - Association:
Book "1" — "0.." Loan(một sách có 0 hoặc nhiều loan). - Aggregation:
Library "1" — "0.." Book,Library "1" — "0.." Member,Library "1" — "0.." Loan(thư viện chứa các thực thể, nhưng các thực thể có thể tồn tại độc lập nếu tách ra). - Dependency:
Loanphụ thuộc vàoBookvàMemberđể xác định ai mượn gì.
6.4. Diagram mẫu (được mô tả bằng PlantUML)
@startuml
package "Domain Model" { class Book { - isbn: String - title: String - author: String - publisher: String - totalCopies: int - availableCopies: int + isAvailable(): boolean + reduceCopy(): void + increaseCopy(): void } class Member { - memberId: String - name: String - email: String - membershipDate: Date + canBorrow(): boolean + addLoan(l: Loan): void } class Loan { - loanId: String - borrowDate: Date - dueDate: Date - returnDate: Date + isOverdue(): boolean + markReturned(d: Date): void } class Library <<facade>> { - books: List<Book> - members: List<Member> - loans: List<Loan> + borrowBook(mId: String, isbn: String): Loan + returnBook(lId: String): void }
} Member "1" --> "0.." Loan
Book "1" --> "0.." Loan
Library "1" --> "0.." Book
Library "1" --> "0.." Member
Library "1" --> "0.." Loan
@enduml
Khi vẽ bằng công cụ đồ họa, chúng ta sẽ:
- Tạo các khung lớp, nhập tên, thuộc tính, phương thức.
- Dùng công cụ “Association” kéo từ
MembertớiLoan, đặt multiplicity1và0... - Đánh dấu
Libraryvới stereotype<<facade>>để nhấn mạnh vai trò trung gian. - Kiểm tra tính nhất quán:
Loankhông có association ngược lại (được thể hiện qua dependency).
7. Các lỗi thường gặp khi vẽ Class Diagram và cách khắc phục
| Lỗi | Mô tả | Cách khắc phục |
|---|---|---|
| Quá tải thông tin | Đặt quá nhiều thuộc tính/phương thức trong một lớp, làm diagram rối mắt. | Tách lớp thành các lớp con hoặc tạo các diagram con (detail diagram). |
| Thiếu multiplicity | Không chỉ định số lượng quan hệ, gây hiểu lầm. | Luôn luôn ghi rõ 1, 0..1, , 1.. trên các đầu mũi tên. |
| Sử dụng Aggregation thay vì Composition sai | Khi phần không thể tồn tại độc lập nhưng lại dùng aggregation. | Xác định tính “ownership” và “life‑cycle”; nếu phần bị hủy khi toàn bộ bị xóa, dùng composition. |
| Kế thừa vòng | Lớp A kế thừa B, B kế thừa C, C lại kế thừa A. | Kiểm tra lại quan hệ kế thừa, tránh vòng. |
| Duplicate attributes | Hai lớp con cùng khai báo cùng thuộc tính, không cần thiết. | Đưa thuộc tính lên lớp cha chung hoặc tạo interface. |
| Không dùng stereotype | Khi các lớp có vai trò đặc biệt (controller, service) mà không có ghi chú. | Thêm stereotype để tăng độ rõ ràng. |
8. Lời khuyên thực tiễn khi làm việc nhóm
- Thiết lập chuẩn naming: Quy ước viết tên lớp, thuộc tính, phương thức (CamelCase, PascalCase) để đồng nhất.
- Sử dụng version control cho file diagram: Đối với PlantUML hoặc các file XML của công cụ, lưu trữ trong Git để theo dõi thay đổi.
- Review định kỳ: Mỗi sprint, tổ chức review diagram để đảm bảo không có “technical debt” ở tầng thiết kế.
- Tích hợp vào CI/CD: Các công cụ như PlantUML có thể tự động sinh ảnh PNG trong pipeline, giúp tài liệu luôn cập nhật.
- Đào tạo người mới: Cung cấp mẫu diagram mẫu và hướng dẫn cách sử dụng công cụ để giảm thời gian học tập.
9. Kết luận
Vẽ class diagram không chỉ là một hoạt động “vẽ hình” mà còn là quá trình phân tích, suy nghĩ và truyền đạt kiến trúc phần mềm. Khi thực hiện đúng quy trình:
- Hiểu rõ yêu cầu → Xác định lớp → Định nghĩa thuộc tính/phương thức → Xây dựng quan hệ → Kiểm tra, tối ưu.
- Kết hợp design patterns, generics, và stereotype giúp diagram trở nên mạnh mẽ, dễ bảo trì.
- Sử dụng công cụ hỗ trợ và thực hành nhóm sẽ giảm thiểu lỗi và nâng cao chất lượng thiết kế.
Hy vọng bài viết này đã cung cấp cho bạn một hướng dẫn chi tiết, từ những kiến thức cơ bản đến các kỹ thuật nâng cao, để bạn có thể tự tin vẽ class diagram cho bất kỳ dự án phần mềm nào. Chúc bạn thành công trong việc thiết kế kiến trúc phần mềm sạch, rõ ràng và dễ bảo trì!
