Read this post in: de_DEen_USes_ESfr_FRhi_INid_IDjapl_PLpt_PTru_RUzh_CNzh_TW

Hướng dẫn toàn diện về sơ đồ lớp UML (Sơ đồ dưới dạng mã)

💡 Ghi chú: Tất cả các sơ đồ đều được cung cấp dưới dạng PlantUML định dạng. Bạn có thể hiển thị chúng ngay lập tức bằng cách sử dụng Visual Paradigm Sơ đồ dưới dạng mã.


🔹 Giới thiệu về UML

UML là gì?

“Ngôn ngữ mô hình hóa thống nhất (UML) là một ngôn ngữ mô hình hóa trực quan mang tính tổng quát, được sử dụng để xác định, trực quan hóa, xây dựng và tài liệu hóa các thành phần của một hệ thống phần mềm.” — Rumbaugh et al., 1999

Đặc điểm chính:

  • 🎨 Ký hiệu trực quan: Ngữ pháp đồ họa để mô hình hóa hệ thống

  • 📐 Tiêu chuẩn hóa: Chuẩn được OMG chấp nhận từ năm 1997

  • 🔧 Ngôn ngữ, không phải là phương pháp: Xác định ký hiệu, không phải quy trình

  • 🌐 Phạm vi rộng: Mô hình hóa các quy trình kinh doanh, chức năng hệ thống, cấu trúc mã nguồn và lược đồ cơ sở dữ liệu

UML KHÔNG PHẢI là gì

Sai lầm phổ biến Thực tế
Một phương pháp phát triển Chỉ là một ký hiệu mô hình hóa
Một ngôn ngữ lập trình Ngôn ngữ mô tả trừu tượng
Chỉ dành cho lập trình hướng đối tượng Áp dụng được cho cơ sở dữ liệu, mô hình hóa kinh doanh, v.v.
Được định nghĩa chính xác ở mọi khía cạnh Vẫn còn một số sự mơ hồ về ngữ nghĩa trong các phiên bản đầu

🔹 Lịch sử và chuẩn hóa

Lộ trình phát triển

The Evolution of Unified Modeling Language (UML)

1965-1970: Simula-67 (ngôn ngữ OO đầu tiên)
     ↓
Thập niên 1970-1980: Smalltalk tại Xerox PARC
     ↓
1984: C++ được Bjarne Stroustrup giới thiệu
     ↓
1988-1992: Sự bùng nổ các phương pháp hướng đối tượng (Booch, OMT, OOSE, v.v.)
     ↓
1994: Rumbaugh gia nhập Booch tại Rational → Bắt đầu quá trình thống nhất
     ↓
1995: Bản nháp UML 0.8 được phát hành
     ↓
1996: OMG phát hành yêu cầu đề xuất (RFP) cho ngôn ngữ mô hình hóa chuẩn
     ↓
1997: UML 1.1 được OMG chấp nhận (ngày 14 tháng 11)
     ↓
2000: UML 1.3 được công bố chính thức
     ↓
2003: UML 1.5 được công bố; cấu trúc siêu cấp UML 2.0 được chấp nhận

Tại sao UML thắng cuộc “Chiến tranh phương pháp”

  • Tập hợp hơn 50 phương pháp hướng đối tượng cạnh tranh thành một chuẩn duy nhất

  • Được hỗ trợ bởi các công ty công nghiệp lớn (IBM, Microsoft, Oracle, HP)

  • Cung cấp các cơ chế mở rộng để tùy chỉnh

  • Trở thành chuẩn thực tế cho mô hình hóa hướng đối tượng

⚠️ Góc nhìn phê phán: Một số cho rằng UML là ‘một ngôn ngữ khổng lồ được thiết kế bởi một ủy ban’ với ngữ nghĩa chưa rõ ràng ở các phiên bản đầu.


🔹 Lớp và Thuộc tính

Cấu trúc lớp

Một lớp UML được biểu diễn dưới dạng hình chữ nhật có tối đa ba ngăn.

@startuml
class Student {
  firstName: String
  lastName: String
  email[0..1]: String
  encryptedPW: String
  + totalPoints(): Integer
  + setPassword(pw: String)
  + checkPW(pw: String): Boolean
}
@enduml

Ngữ pháp khai báo thuộc tính

[quyền truy cập] tên[số lượng]: Kiểu [= giá trị mặc định] {tính chất}

Ví dụ PlantUML:

@startuml
class Student {
  + ProgramOfStudy[0..2]: String = "MIS"
  - encryptedPW: String {frozen}
  # internalID: Integer
  ~ packagePrivateData: String
}
@enduml

Phạm vi thuộc tính

  • Phạm vi thể hiện (mặc định): Mỗi đối tượng có giá trị riêng của nó

  • Phạm vi lớp (tĩnh): Giá trị duy nhất được chia sẻ bởi tất cả các thể hiện

@startuml
class Student {
  name: String
  {static} count: Integer
}
@enduml

Khóa trong UML ⚠️

Hạn chế quan trọng: UML không có khái niệm tích hợp về khóa. Sử dụng các kiểu dáng hoặc giá trị gắn thẻ như giải pháp thay thế.

@startuml
class Student {
  {pk} id: Integer
  {ak1} email: String
  - name: String
}
@enduml


🔹 Liên kết và mối quan hệ

Liên kết cơ bản và bội số

@startuml
class Exercise
class Chapter
Exercise "0..*" -- "1..1" Chapter : Thuộc về
@enduml

Giải thích: Mỗi bài tập thuộc về đúng một chương; một chương có thể chứa không hoặc nhiều bài tập.

Tên vai trò

Thay vì (hoặc ngoài tên liên kết), hãy sử dụng tên vai trò ở các đầu nối kết:

@startuml
class Person
class Company
Person "0..*" --> "0..1" Company : Nhân viên/Nhà tuyển dụng
@enduml

Triển khai: Những Người bảng sẽ có khóa ngoại người sử dụng lao động tham chiếu đến Công ty.

Khả năng di chuyển

Xác định hướng di chuyển bằng các mũi tên:

@startuml
class Bài tập
class Chương
Bài tập "0..*" --> "1" Chương
@enduml

  • Mũi tên chỉ hướng di chuyển hiệu quả

  • Trong OODBs: triển khai như con trỏ chỉ theo một hướng

  • Trong RDBMS: các phép nối hoạt động theo cả hai hướng bất kể

Loại tập hợp với {theo thứ tự}

@startuml
class Chương
class Bài tập
Chương "1" -- "0..*" Bài tập : {theo thứ tự}
@enduml

  • {theo thứ tự}: Duy trì thứ tự (sử dụng danh sách, không phải tập hợp)

  • Triển khai trong RDBMS: Thêm thuộc tính số thứ tự

BÀI TẬP (
    id PRIMARY KEY,
    chapter_id tham chiếu đến CHƯƠNG,
    sort_no INTEGER,
    UNIQUE (chapter_id, sort_no)
)

Các bộ lọc

Các bộ lọc chia nhỏ các đối tượng liên quan bằng cơ chế giống như khóa:

@startuml
class Chapter
class Exercise
Chapter "1" --> "0..1" Exercise : <<chỉ định>> no: Integer
@enduml

Ý nghĩa: Với một Chương và một số bài tập, tối đa chỉ trả về một Bài tập.

Lớp liên kết

Khi một liên kết có thuộc tính hoặc thao tác:

@startuml
class Student
class Exercise
class Solution {
  date: Date
  points: Integer
}
Student "0..*" -- "0..*" Exercise : đã giải
Solution .. Student
Solution .. Exercise
@enduml

  • Một Giải pháp đối tượng cho mỗi cặp (Học sinh, Bài tập)

  • Bắt buộc: cùng một học sinh không thể nộp hai giải pháp cho cùng một bài tập

Thành phần hóa so với tích hợp

Tính năng Thành phần hóa (*--) Tích hợp (o--)
Ký hiệu Kim cương đen Kim cương trắng
Mối quan hệ Toàn thể-phần, sở hữu mạnh Toàn thể-phần, tham chiếu yếu
Chu kỳ sống Các bộ phận bị xóa cùng với toàn bộ Các bộ phận độc lập
Đa dạng 1 hoặc 0..1 ở phía toàn bộ Bất kỳ
Ánh xạ RDBMS ON DELETE CASCADE Khóa ngoại tiêu chuẩn
@startuml
class Chapter
class Exercise
Chapter *-- "0..*" Exercise : Thành phần
Chapter o-- "0..*" Exercise : Kết hợp
@enduml


🔹 Các thao tác và phương thức

Ngữ pháp khai báo thao tác

@startuml
class Calculator {
  + getTotal(studID: Integer, inclExtra: Boolean = true): Float {isQuery=true}
  + {static} getInstance(): Calculator
  + {constructor} Calculator(initialValue: Float)
  - recalculate(): void
}
@enduml

Cụ thể hóa tham số:

[hướng] tên: Kiểu [= giá trị mặc định]
  • Hướng: vào (mặc định), ravào-ra

  • Giá trị mặc định cho phép tham số tùy chọn

Các kiểu đặc biệt cho thao tác

Chủng loại Mục đích
{isQuery=true} Đảm bảo không thay đổi trạng thái
{constructor} Tạo và khởi tạo các thể hiện mới
{static} Thao tác ở cấp lớp, không ngầm địnhself

Các thao tác trong ngữ cảnh cơ sở dữ liệu

Sự xung đột văn hóa: OO nhấn mạnh đóng gói; quan hệ nhấn mạnh truy cập dữ liệu trực tiếp.

Chiến lược triển khai:

Loại thao tác Triển khai RDBMS
Truy cập thuộc tính đơn giản SELECT/UPDATE trực tiếp
Thuộc tính suy ra (không tham số) VIEW cơ sở dữ liệu
Thuộc tính suy ra (có tham số) Thủ tục lưu trữ hoặc logic ứng dụng
Thực thi ràng buộc phức tạp Triggers hoặc thủ tục ứng dụng

🔹 Tổng quát hóa và kế thừa

Tổng quát hóa cơ bản

@startuml
class Person
class Student
class Professor
Person <|-- Student
Person <|-- Professor
@enduml

Lớp trừu tượng và thao tác

@startuml
lớp trừu tượng Account {
  - balance: Float
  + deposit(amount: Float): void
  + {abstract} withdraw(amount: Float): void
}
@enduml

Ràng buộc tổng quát hóa

@startuml
class Person
class Student
class Professor
class OtherPerson
Person <|-- Student : <<{không giao nhau, đầy đủ}>>
Person <|-- Professor : <<{không giao nhau, đầy đủ}>>
Person <|-- OtherPerson : <<{không giao nhau, đầy đủ}>>
@enduml

Phân loại nhiều lớp / Bộ phân biệt

@startuml
class Employee
class Staff
class Faculty
class HMO
class NonHMO
Employee <|-- Staff : <<loại>>
Employee <|-- Faculty : <<loại>>
Employee <|-- HMO : <<bảo hiểm>>
Employee <|-- NonHMO : <<bảo hiểm>>
@enduml

  • Các bộ phân biệt nhóm các đặc tả loại trừ lẫn nhau

  • Các đối tượng có thể có một giá trị cho mỗi chiều bộ phân biệt


🔹 Cơ chế mở rộng

UML cung cấp ba cơ chế mở rộng:

1. Stereotype<< >>

Mở rộng ngữ nghĩa UML bằng cách tạo ra các “loại con” mới từ các phần tử mô hình siêu cấp.

@startuml
class Customer <<entity>> {
  - id: Integer
  - name: String
}
class MathLibrary <<utility>> {
  + sin(x: Float): Float
  + cos(x: Float): Float
}
@enduml

2. Giá trị gắn thẻ{key=value}

Thêm các thuộc tính tùy chỉnh vào các phần tử mô hình.

@startuml
class Student {
  {author=sb, version=1.0, persistence=persistent}
  - id: Integer
}
@enduml

3. Ràng buộc {...}

Thêm các giới hạn ngữ nghĩa bằng văn bản tự do, OCL hoặc các chữ viết tắt đã định sẵn.

@startuml
class Exercise {
  - no: Integer
  - points: Integer {value >= 0}
  {points <= maxPoints}
}
@enduml


🔹 UML cho thiết kế cơ sở dữ liệu: Những điểm cần lưu ý chính

Chuyển đổi UML sang lược đồ quan hệ

Cấu trúc UML Triển khai quan hệ
Lớp Bảng
Thuộc tính Cột
Khóa chính {pk} Ràng buộc PRIMARY KEY
Liên kết (1:*) Khóa ngoại ở phía “nhiều”
Liên kết (:) Bảng giao nhau/bảng giao điểm
Thành phần Khóa ngoại + ON DELETE CASCADE
Lớp liên kết Bảng với khóa ngoại kết hợp + thuộc tính
Tổng quát hóa Bảng riêng lẻ (với khóa ngoại) hoặc bảng duy nhất với bộ phân biệt kiểu
{có thứ tự}liên kết Thêm cột thứ tự + ràng buộc duy nhất
Chỉ định Một phần của khóa kết hợp hoặc cột được chỉ mục

Sự khác biệt quan trọng: Hướng đối tượng so với quan hệ

Khía cạnh Hướng đối tượng Quan hệ
Định danh Tham chiếu đối tượng (thay thế) Khóa chính (kinh doanh hoặc thay thế)
Thao tác Cốt lõi trong thiết kế, đóng gói Bên ngoài (SQL, thủ tục)
Đóng gói Thuộc tính riêng tư, giao diện công khai Truy cập bảng trực tiếp theo mặc định
Kế thừa Hỗ trợ ngôn ngữ bản địa Chiến lược ánh xạ phức tạp
Mối quan hệ Con trỏ/tham chiếu Khóa ngoại và nối kết

Gợi ý thực tiễn cho người thiết kế cơ sở dữ liệu

  1. Mô hình hóa rõ ràng các khóa: Sử dụng {pk}{ak1} các kiểu dáng vì UML không hỗ trợ khóa tích hợp

  2. Ghi chú tính bền vững: Sử dụng {persistent} giá trị gắn nhãn để phân biệt các lớp cơ sở dữ liệu với các lớp ứng dụng tạm thời

  3. Đơn giản hóa thao tác: Ánh xạ các thao tác truy vấn sang các view; các thao tác phức tạp sang các thủ tục lưu trữ

  4. Xử lý kế thừa cẩn thận: Chọn chiến lược ánh xạ dựa trên các mẫu truy vấn

  5. Tài liệu các ràng buộc: Sử dụng OCL hoặc ràng buộc văn bản rõ ràng cho các quy tắc kinh doanh

  6. Sử dụng lớp liên kết một cách thận trọng: Chỉ khi mối quan hệ có các thuộc tính quan trọng


🎯 Bản tóm tắt tham khảo nhanh

Tóm tắt ký hiệu sơ đồ lớp PlantUML

@startuml
class <<kiểu dáng>> ClassName {
  {tagged=value}
  [+/-/#/~] name[mult]: Type [= val] {props}
  [+/-/#/~] name(params): Ret {props}
}
@enduml

Ký hiệu liên kết

@startuml
ClassA "multA" -- "multB" ClassB : AssociationName
ClassA *-- ClassB  ' Tích hợp
ClassA o-- ClassB  ' Tích hợp
ClassA --> ClassB  ' Có thể điều hướng
@enduml

Các ký hiệu tính khả kiến

  • + Công khai

  • - Riêng tư

  • # Bảo vệ

  • ~ Gói

Các thuộc tính và ràng buộc chung

  • {tĩnh} / {là truy vấn=true} / {trừu tượng}

  • {giá trị >= 0} / {xor} / {có thứ tự} / {khóa chính}


💡 Suy nghĩ cuối cùng: Sơ đồ lớp UML rất mạnh mẽ cho mô hình hóa khái niệm, nhưng hãy nhớ chúng được thiết kế chủ yếu cho kỹ thuật phần mềm. Khi sử dụng UML cho thiết kế cơ sở dữ liệu, hãy sẵn sàng mở rộng ký hiệu (bằng các kiểu dáng, giá trị gắn thẻ, ràng buộc) để ghi lại các khái niệm quan hệ như khóa, chuẩn hóa và các ràng buộc khai báo mà không phải là bản chất của nền tảng hướng đối tượng của UML.

Hướng dẫn được biên soạn từ “Phần 6: Sơ đồ lớp UML” của Stefan Brass, Đại học Halle, 2003. Tất cả các sơ đồ được định dạng theo cú pháp PlantUML để tương thích với các công cụ hiện đại.

Leave a Reply