de_DEen_USes_ESfa_IRfr_FRhi_INid_IDjapl_PLpt_PTru_RUvizh_CNzh_TW

Thu nhỏ Tối Đa: Hiểu Về Sơ Đồ Mã Nguồn C4 – Chúng Là Gì, Khi Nào Tạo Giá Trị, Và Các Ví Dụ Thực Tế Với PlantUML

Sơ đồ mã nguồn C4 là gì?

Sơ đồ mã nguồn làMức 4— mức sâu nhất, chi tiết nhất trong mô hình C4 của Simon Brown.

The Ultimate Guide to C4 Model Visualization with Visual Paradigm's AI Tools - ArchiMetric

Nó thể hiện:

  • Lớpgiao diệnenumbản ghi, hoặc các cấu trúc cấp mã nguồn khác thực hiện một thành phần cụ thểthành phần (từ Mức 3).

  • Mối quan hệ giữa các lớp đó (kế thừa, tổng hợp, phụ thuộc, thực hiện giao diện, v.v.).

  • Các yếu tố thiết kế chínhyếu tố thiết kế như các mẫu được áp dụng bên trong thành phần (ví dụ: kho lưu trữ, dịch vụ, DTO, thực thể miền, nhà máy).

Trong thực tế, mức này gần như luôn là mộtsơ đồ lớp UML (hoặc một biến thể đơn giản hóa) tập trung vào một (hoặc rất ít) thành phần.

Lưu ý quan trọng:

  • Mức 4 làkhông về toàn bộ cơ sở mã nguồn.

  • Nó làkhôngbắt buộc phải hiển thị mọi lớp.

  • Nó ánh xạ chỉ cấu trúc thiết yếucần thiết để hiểu cách một thành phần phức tạp hoặc quan trọng thực sự được xây dựng.

  • Khuyến nghị chính thức của C4: lý tưởng là được sinh tự độngtừ mã nguồn (thông qua các công cụ như Doxygen, Javadoc + plugin UML, yWorks, Structurizr, CodeSee, v.v.) thay vì vẽ tay.

Khi nào nên tạo sơ đồ mã nguồn

Tạo sơ đồ cấp độ 4 một cách tiết kiệm — chỉ trong những tình huống này:

  • Thành phần này là rất phức tạpchiến lược, quan trọng, hoặc khó hiểuchỉ từ mã nguồn (ví dụ: logic miền phức tạp, sử dụng nặng các mẫu thiết kế, luồng mã hóa, máy trạng thái, mã nguồn cũ đầy nợ kỹ thuật).

  • Bạn đang làm việc trong một ngành công nghiệp bị quản lý nghiêm ngặt (tài chính, y tế, hàng không vũ trụ, quốc phòng) nơi các kiểm toán viên hoặc nhóm tuân thủ yêu cầu ánh xạ rõ ràng từ kiến trúc → thiết kế → triển khai.

  • Trong quá trình tái cấu trúc lớnlàm suy yếu một thành phần cũ, hoặc giới thiệu một mẫu kiến trúc mới (hình chữ nhật, sạch, lát dọc, tập hợp DDD) — các hình ảnh trước/sau giúp truyền đạt sự thay đổi.

  • Chào đón lập trình viên cấp cao hoặc kiến trúc sưnhững người cần nắm nhanh cấu trúc nội bộ không rõ ràng của một đoạn mã có rủi ro cao.

  • Bạn đã đầu tư vào tự động sinhcông cụ — do đó việc duy trì cấp độ 4 gần như không tốn kém gì.

  • Đội đã đồng ý rằng “tài liệu sống”ở cấp độ lớp là có giá trị đối với hệ thống con cụ thể này.

Không tạo sơ đồ cấp độ 4 khi:

  • Cấu trúc thành phần rõ ràng từ tên gọi tốt, kích thước nhỏ, hoặc mã sạch (hầu hết dịch vụ vi mô hiện đại đều thuộc nhóm này).

  • Bạn đã có sẵn bộ kiểm thử đơn vị/tích hợp tốtgiao diện rõ ràng, và các nhận xét giải thích.

  • Hầu hết thành viên trong đội có thể di chuyển qua mã nguồn một cách dễ dàng.

  • Chi phí bảo trì vượt quá lợi ích (sơ đồ lớp vẽ tay nhanh lỗi thời).

Simon Brown và phần lớn các chuyên gia nhấn mạnh: Hầu hết các đội không bao giờ cần cấp độ 4Cấp độ 1 + 2phủ khoảng 80–90% nhu cầu giao tiếp; Cấp độ 3xử lý phần lớn phần còn lại. Cấp độ 4 là ngoại lệ, không phải quy luật.

Tại sao nên sử dụng sơ đồ mã nguồn? (Khi chúng mang lại giá trị)

  • Cầu nối giữa kiến trúc ↔ triển khai — Cho thấy cách các thành phần cấp cao thực sự được triển khai trong mã nguồn.

  • Làm rõ thiết kế nội bộ phức tạp — Bộc lộ việc sử dụng các mẫu (Chiến lược, Nhà máy, Bộ trang trí, Kho lưu trữ), vi phạm phân lớp, sự gắn kết chặt chẽ, hoặc mô hình hóa miền thông minh.

  • Hỗ trợ kiểm toán và tuân thủ — Chứng minh rằng các quyết định kiến trúc được thực hiện đúng trong mã nguồn.

  • Hỗ trợ các cuộc thảo luận về tái cấu trúc và di chuyển — Cấu trúc lớp trước/sau giúp các đề xuất trở nên cụ thể hơn.

  • Giảm thiểu “kiến thức dân tộc” — Giúp những nhân viên cấp cao mới hiểu nhanh các phần phức tạp hơn so với việc đọc tất cả các tệp nguồn.

  • Các phiên bản được tạo tự động trở thành “tài liệu sống” — Nếu công cụ đã được triển khai, chúng sẽ luôn chính xác với gần như không cần nỗ lực.

Làm thế nào để tạo một sơ đồ mã nguồn tuyệt vời (Bước từng bước + Thực hành tốt nhất)

  1. Chọn MỘT thành phần — Thường đến từ sơ đồ cấp 3, nơi độ phức tạp bên trong lý giải được việc phóng to.

  2. Quyết định: vẽ tay hay tạo tự động?

    • Vẽ tay → chỉ dùng cho các buổi làm việc nhóm, đề xuất, hoặc các khu vực quá lộn xộn để công cụ tự động xử lý.

    • Tạo tự động → được ưu tiên (PlantUML vẫn có thể dùng để định dạng/tinh chỉnh đầu ra).

  3. Tập trung vào những điều thiết yếu — Hiển thị:

    • Lớp và giao diện chính

    • Các mối quan hệ quan trọng (→ phụ thuộc, — kết hợp, <| thực hiện, ^ kế thừa)

    • Các tập hợp, thực thể, đối tượng giá trị (theo phong cách DDD)

    • Các mẫu hoặc mẫu sai bạn muốn làm nổi bật

  4. Giữ cho nhỏ gọn — Tối đa 8–15 lớp. Nếu lớn hơn → chia thành các sơ đồ tập trung (ví dụ: “mảnh Xác thực”, “thực thể xử lý đơn hàng”).

  5. Thực hành tốt nhất

    • Ưu tiên tạo tự động mọi lúc có thể (ít lỗi thời hơn).

    • Sử dụng cú pháp PlantUML classDiagram cú pháp — sạch sẽ và có thể kiểm soát phiên bản.

    • Thêm ghi chú đối với các quyết định không rõ ràng (ví dụ: “Sử dụng Mô hình miền mỏng – đã lên kế hoạch tái cấu trúc”).

    • Tránh hiển thị mọi thứ — bỏ qua các phương thức truy xuất/đặt giá trị đơn giản, các lớp tiện ích.

    • Lưu trong kho → xử lý như mã nguồn (gửi tệp .puml gần thành phần).

    • Sử dụng hạn chế — một cho mỗi thành phần phức tạp, không phải mỗi microservice.

    • Kết hợp với các chế độ xem động (sequence/collaboration) nếu luồng thời gian chạy quan trọng hơn cấu trúc tĩnh.

Ví dụ PlantUML – Thành phần Xác thực (mở rộng theo phong cách Big Bank plc)

Dưới đây là một ví dụ cấp độ 4 thực tế, phóng to vào Thành phần Bảo mật / Xác thực từ các sơ đồ Ứng dụng API trước đó.

@startuml
title C4 Cấp độ 4 – Sơ đồ Mã nguồn: Xác thực bên trong Ứng dụng API

skinparam monochrome true
skinparam shadowing false
skinparam class {
  BackgroundColor White
  BorderColor Black
  ArrowColor Black
}

abstract class AuthenticationProvider {
  + authenticate(credentials): Authentication
}

class JwtAuthenticationProvider {
  - tokenProvider: JwtTokenProvider
  - userDetailsService: UserDetailsService
  + authenticate(credentials): Authentication
}

class JwtTokenProvider {
  - secretKey: String
  - validityInMilliseconds: long
  + generateToken(userDetails): String
  + validateToken(token): boolean
  + getUsernameFromToken(token): String
}

interface UserDetailsService {
  + loadUserByUsername(username): UserDetails
}

class DatabaseUserDetailsService {
  - userRepository: UserRepository
  + loadUserByUsername(username): UserDetails
}

class UserRepository {
  + findByUsername(username): Optional<User>
}

class User {
  - username: String
  - passwordHash: String
  - roles: Set<Role>
}

class JwtAuthenticationToken << (T,orchid) Authentication >> {
  - principal: UserDetails
  - credentials: Object
  - authorities: Collection<GrantedAuthority>
}

' Mối quan hệ
JwtAuthenticationProvider -up-> JwtTokenProvider : sử dụng
JwtAuthenticationProvider -up-> UserDetailsService : sử dụng
DatabaseUserDetailsService .up.|> UserDetailsService
DatabaseUserDetailsService --> UserRepository : sử dụng
UserRepository --> User : trả về

JwtAuthenticationToken .up.|> Authentication

note right of JwtAuthenticationProvider
  Luồng xác thực chính cho các phiên không trạng thái dựa trên JWT
end note

note bottom of JwtTokenProvider
  Ký và xác minh JWT bằng HS512
end note

@enduml

Sơ đồ nhỏ này:

  • Chỉ tập trung vào nội bộ xác thực

  • Hiển thị các lớp chính, giao diện và phụ thuộc

  • Nhấn mạnh các mẫu (cung cấp, kho lưu trữ)

  • Sử dụng ghi chú để cung cấp bối cảnh

Dán vào bất kỳ trình render PlantUML nào — tùy chỉnh cho miền của bạn (ví dụ: thay JWT bằng OAuth2, thêm lớp MFA, v.v.).

Lời nhắc tóm tắt: Cấp độ 4 rất mạnh mẽ nhưng hiếm. Sử dụng một cách có chủ ý, ưu tiên tự động hóa, và đừng để nó trở thành công việc vô bổ. Phần lớn giá trị trong C4 đến từ các cấp độ 1–3. Chúc bạn (chọn lọc) mô hình hóa vui vẻ!

Tài nguyên

This post is also available in Deutsch, English, Español, فارسی, Français, English, Bahasa Indonesia, 日本語, Polski, Portuguese, Ру́сский, 简体中文 and 繁體中文.