Sử dụng UML hiệu quả cho Kiến trúc sư giải pháp – Phần 3

Cấu trúc Giải pháp – Biểu đồ Lớp và Biểu đồ Thành phần

3.1. Giới thiệu: Xây dựng Bộ khung Tĩnh cho Hệ thống

Sau khi đã xác định rõ hệ thống cần làm gì thông qua các biểu đồ hành vi, bước tiếp theo của một Solution Architect là thiết kế cấu trúc bên trong của nó. Đây là lúc chúng ta chuyển từ “cái gì” sang “cái như thế nào”. Giai đoạn này tập trung vào việc xây dựng bộ khung tĩnh, xương sống của hệ thống. Hai công cụ mạnh mẽ nhất cho việc này là Biểu đồ Lớp (Class Diagram) và Biểu đồ Thành phần (Component Diagram). Chúng đóng vai trò như những bản thiết kế chi tiết cho mã nguồn và kiến trúc tổng thể.

3.2. Nền tảng của Mọi Hệ thống: Làm chủ Biểu đồ Lớp

Biểu đồ Lớp là biểu đồ UML phổ biến và cơ bản nhất. Nó là trái tim của bất kỳ hệ thống hướng đối tượng nào, mô tả cấu trúc tĩnh của hệ thống bằng cách hiển thị các lớp, thuộc tính (dữ liệu), phương thức (hành vi) và các mối quan hệ giữa chúng.

Các thành phần cốt lõi của một Biểu đồ Lớp:

  • Lớp (Class): Là một bản thiết kế (blueprint) cho các đối tượng, được biểu diễn bằng một hình chữ nhật chia làm ba phần: Tên lớp, Thuộc tính (Attributes), và Phương thức (Operations/Methods).
  • Thuộc tính (Attributes): Là các dữ liệu hoặc đặc điểm mà một lớp sở hữu. Ví dụ: trong lớp Account, có thể có thuộc tính accountNumber: string và balance: double.
  • Phương thức (Operations): Là các hành động mà một lớp có thể thực hiện. Ví dụ: lớp Account có các phương thức deposit(amount: double) và withdraw(amount: double).
  • Tầm vực (Visibility): Xác định mức độ truy cập của thuộc tính và phương thức:
    • + Public: Có thể truy cập từ bất cứ đâu.
    • – Private: Chỉ có thể truy cập bên trong chính lớp đó.
    • # Protected: Có thể truy cập bên trong lớp đó và các lớp con kế thừa từ nó.

Các mối quan hệ quan trọng giữa các lớp:

  • Association (Liên kết): Mối quan hệ chung nhất, thể hiện sự kết nối ngữ nghĩa giữa hai lớp. Ví dụ, một Customer “sử dụng” một Account. Nó thường được biểu diễn bằng một đường thẳng.
  • Aggregation (Tập hợp): Là một dạng đặc biệt của Association, biểu thị mối quan hệ “có một” (has-a) nhưng các thành phần có thể tồn tại độc lập. Ví dụ, một Bank “có” nhiều Customer. Nếu ngân hàng đó không còn, các khách hàng vẫn tồn tại. Quan hệ này được biểu diễn bằng đường thẳng với một hình thoi rỗng ở phía toàn thể.
  • Composition (Hợp thành): Là một dạng Aggregation mạnh hơn, biểu thị mối quan hệ “sở hữu” (owns-a), nơi mà thành phần con không thể tồn tại nếu không có toàn thể. Ví dụ, một Account “sở hữu” các Transaction. Nếu tài khoản bị xóa, tất cả các giao dịch của nó cũng bị xóa theo. Quan hệ này được biểu diễn bằng đường thẳng với một hình thoi đặc ở phía toàn thể.
  • Generalization (Tổng quát hóa / Kế thừa): Biểu thị mối quan hệ “là một” (is-a). Ví dụ, SavingsAccount (Tài khoản tiết kiệm) và CheckingAccount (Tài khoản thanh toán) “là một” loại Account. Nó được biểu diễn bằng một đường thẳng với mũi tên tam giác rỗng chỉ về phía lớp cha.

Ví dụ thực tế: Mô hình Miền (Domain Model) cho Hệ thống Ngân hàng Trực tuyến

Chúng ta sẽ thiết kế một Biểu đồ Lớp cho hệ thống ngân hàng, bao gồm các lớp như Customer, Account, SavingsAccount, CheckingAccount, Transaction, Bank, và Branch. Biểu đồ sẽ thể hiện rõ:

  • Customer có các thuộc tính như name, address và có mối quan hệ liên kết (association) với Account.
  • Account là một lớp cha trừu tượng (tên in nghiêng), có các thuộc tính chung như accountNumber, balance và các phương thức chung như deposit(), withdraw().
  • SavingsAccount và CheckingAccount kế thừa từ Account, và có thêm các thuộc tính riêng (ví dụ: interestRate cho SavingsAccount).
  • Một Bank có thể có nhiều Branch (quan hệ Composition, vì chi nhánh không thể tồn tại nếu không có ngân hàng).
  • Một Branch có thể có nhiều Account (quan hệ Aggregation, vì tài khoản có thể được chuyển sang chi nhánh khác).

Một SA không chỉ dùng Biểu đồ Lớp để ra lệnh cho lập trình viên. Họ sử dụng nó như một công cụ khám phá, hợp tác với các nhà phân tích nghiệp vụ và chuyên gia tên miền để làm sáng tỏ bản chất thực sự của lĩnh vực kinh doanh. Quá trình mô hình hóa các lớp và mối quan hệ của chúng thường bộc lộ các quy tắc nghiệp vụ ẩn, những điểm mơ hồ hoặc các giả định sai lầm. Một cuộc tranh luận về việc một mối quan hệ nên là Aggregation hay Composition thực chất là một cuộc tranh luận về một quy tắc kinh doanh nền tảng. Ví dụ, “Một khách hàng có thể tồn tại trong hệ thống mà không có tài khoản nào không?”. Câu trả lời cho câu hỏi này sẽ quyết định mối quan hệ giữa Customer và Account và có ảnh hưởng trực tiếp đến thiết kế hệ thống. Bằng cách tạo ra Biểu đồ Lớp, SA buộc những câu hỏi này phải được đưa ra ánh sáng và giải quyết một cách tường minh. Biểu đồ kết quả không chỉ là một tài liệu kỹ thuật, mà là một sự hiểu biết chung đã được xác thực về lĩnh vực kinh doanh—một nền tảng vững chắc hơn nhiều cho dự án.

3.3. Từ Lớp đến Hệ thống: Hướng dẫn về Biểu đồ Thành phần

Khi hệ thống trở nên phức tạp, việc chỉ nhìn vào các lớp riêng lẻ là không đủ. Chúng ta cần một cái nhìn ở tầm cao hơn, xem hệ thống được tổ chức thành các khối kiến trúc lớn hơn như thế nào. Đó là lúc Biểu đồ Thành phần phát huy tác dụng. Nó cho thấy cách một hệ thống phức tạp được chia thành các thành phần (component) modular, có thể thay thế và tái sử dụng, cùng với các phụ thuộc và giao diện (interface) giữa chúng.

Các thành phần cốt lõi của một Biểu đồ Thành phần:

  • Thành phần (Component): Một phần modular của hệ thống, có thể là một thư viện (.dll,.jar), một file thực thi (.exe), một tập hợp các lớp có liên quan, hoặc một dịch vụ (service). Nó được biểu diễn bằng một hình chữ nhật với biểu tượng thành phần nhỏ ở góc.
  • Giao diện (Interface): Một tập hợp các phương thức định nghĩa một “hợp đồng” dịch vụ. Một thành phần có thể cung cấp (provide) một giao diện (dịch vụ mà nó cung cấp) và yêu cầu (require) một giao diện (dịch vụ mà nó cần từ thành phần khác).
  • Provided Interface (Ký hiệu Lollipop): Biểu diễn bằng một đường thẳng có hình tròn ở cuối, cho thấy dịch vụ mà thành phần đó cung cấp cho thế giới bên ngoài.
  • Required Interface (Ký hiệu Socket): Biểu diễn bằng một đường thẳng có hình bán nguyệt, cho thấy dịch vụ mà thành phần đó cần từ một thành phần khác để hoạt động.
  • Port: Một điểm tương tác cụ thể trên một thành phần, được biểu diễn bằng một hình vuông nhỏ trên cạnh của thành phần, thường được dùng để nhóm các giao diện.
  • Dependency (Phụ thuộc): Mũi tên nét đứt chỉ ra rằng một thành phần phụ thuộc vào một thành phần khác.

Ví dụ thực tế: Kiến trúc Nền tảng Thương mại Điện tử

Hãy mô hình hóa một hệ thống thương mại điện tử với các thành phần sau:

  • WebAppUI: Thành phần giao diện người dùng web.
  • ProductCatalogService: Dịch vụ quản lý danh mục sản phẩm. Nó cung cấp một giao diện IProductSearch.
  • ShoppingCartService: Dịch vụ quản lý giỏ hàng. Nó yêu cầu giao diện IProductSearch từ ProductCatalogService để lấy thông tin sản phẩm.
  • PaymentGateway: Thành phần cổng thanh toán bên ngoài.
  • OrderManagementService: Dịch vụ quản lý đơn hàng. Nó cung cấp giao diện IOrderProcessing và phụ thuộc vào PaymentGateway.

Trong kiến trúc hiện đại, Biểu đồ Thành phần là bản quy hoạch tổng thể của SA để triển khai các mô hình như Kiến trúc hướng dịch vụ (SOA) hay Microservices. Nó không chỉ là việc nhóm các lớp lại với nhau; nó là việc định nghĩa các “hợp đồng” (interfaces/APIs) giữa các dịch vụ có thể triển khai độc lập. Đây là chìa khóa để đạt được khả năng mở rộng, tính bền vững và sự tự chủ của các đội phát triển. Mỗi microservice có thể được xem như một

Component. API của nó là Provided Interface. Các phụ thuộc của nó vào các dịch vụ khác là Required Interfaces. Bằng cách thiết kế ở cấp độ này, SA có thể lên kế hoạch cho toàn bộ cảnh quan hệ thống, phân công các dịch vụ cho các đội khác nhau, và đảm bảo rằng miễn là các giao diện được tôn trọng, các đội có thể phát triển, triển khai và mở rộng dịch vụ của họ một cách độc lập. Biểu đồ này trở thành tài liệu nền tảng cho một nỗ lực phát triển phân tán quy mô lớn.


Bình luận về bài viết này