← C4 Model: vẽ kiến trúc phần mềm

Bài 1 · Cơ bản · 16 phút

Vì sao sơ đồ kiến trúc gây rối

Biên soạn bởi Nguyễn Anh Tuấn

Thực trạng bản vẽ kiến trúc: hộp & mũi tên tuỳ hứng, thiếu chú giải, trộn nhiều mức trừu tượng. C4 Model là gì: bản đồ hệ thống ở nhiều mức zoom (Simon Brown).

Hãy tưởng tượng một buổi họp lên kế hoạch cho hệ thống mới. Ai đó cầm bút lông, vẽ vài cái hộp lên bảng trắng rồi nối chúng bằng mũi tên. Một hộp ghi "Server", một hộp ghi "DB", một hộp là tên một class, một hộp là "Người dùng", còn có hộp ghi tên một hãng cloud. Mũi tên chằng chịt, không cái nào có nhãn.

Mọi người gật gù. Nhưng nếu hỏi riêng từng người "mũi tên này nghĩa là gì?", bạn sẽ nhận được ba câu trả lời khác nhau: người bảo đó là một lời gọi API, người bảo đó là luồng dữ liệu, người lại hiểu là phụ thuộc lúc biên dịch. Tấm bảng trông như có sự đồng thuận, nhưng thực ra mỗi cái đầu đang giữ một bức tranh riêng.

Nỗi đau khi lên kế hoạch

Sơ đồ kiến trúc hay là thứ ai cũng vẽ nhưng không ai vẽ giống ai. Khi bức tranh trong đầu mỗi người một khác, kế hoạch xây trên đó cũng lệch theo - và chi phí của sự hiểu lầm này chỉ lộ ra lúc đã viết code.

Vì sao một sơ đồ "vẽ cho có" lại dễ gây hiểu lầm đến vậy? Thường vì ba căn bệnh sau:

  • Mũi tên mơ hồ: một mũi tên có thể là gọi API, luồng dữ liệu, hay phụ thuộc - không ghi rõ thì mỗi người đoán một kiểu.
  • Thiếu chú giải (legend): hộp vuông, hộp tròn, màu xanh, màu đỏ... mỗi thứ ngụ ý gì? Không có chú giải thì người đọc tự bịa luật.
  • Trộn nhiều mức trừu tượng: một hộp là cả một hệ thống, hộp ngay cạnh lại là một class - như tấm bản đồ vừa vẽ cả thế giới vừa vẽ một con hẻm.

Căn bệnh thứ ba là nặng nhất. Khi cả hệ thống và một mẩu code nhỏ cùng nằm trên một sơ đồ, người đọc không biết đang nhìn ở "độ cao" nào, nên không thể suy luận đúng về tổng thể.

Giả sử bạn vẽ ra một sơ đồ thật đẹp. Vấn đề tiếp theo: bạn sẽ trình bày nó cho ai? Mỗi phòng ban cần một mức chi tiết khác hẳn nhau:

  • Sếp kinh doanh / sales: chỉ cần biết "hệ thống làm gì, ai dùng, nối với dịch vụ nào" - không quan tâm database tên gì.
  • Quản lý dự án (PM): muốn thấy các khối lớn để chia việc và ước lượng - web, mobile, API, dữ liệu.
  • Lập trình viên: cần chi tiết bên trong một khối để biết viết code ở đâu.
  • Vận hành (ops): quan tâm cái gì chạy ở đâu, triển khai ra sao.

Một sơ đồ đủ chi tiết cho lập trình viên sẽ làm người kinh doanh mù mịt; một sơ đồ gọn cho sếp lại khiến lập trình viên thiếu thông tin. Cố vẽ một bức làm hài lòng tất cả thường thành bức không phục vụ tốt cho ai.

Gốc rễ vấn đề

Không có "sơ đồ kiến trúc" duy nhất đúng. Cái ta cần là nhiều góc nhìn ở nhiều mức chi tiết, và một cách thống nhất để biết mình đang ở mức nào - khi nói chuyện với ai.

Đây chính là chỗ C4 Model bước vào. C4 do Simon Brown đề xuất, là một cách nhìn kiến trúc phần mềm như một bộ bản đồ ở nhiều mức zoom - y như Google Maps.

Trên Google Maps, bạn zoom ra để thấy cả đất nước, zoom vào nữa thấy thành phố, vào nữa thấy khu phố, rồi tới từng con đường. Mỗi mức là cùng một thực tại, chỉ khác độ chi tiết - và mỗi mức hữu ích cho một mục đích khác nhau. C4 áp đúng ý đó cho phần mềm, với bốn mức (chữ "C" là viết tắt của bốn cái tên):

1 · ContextHệ thống nằm giữa, người dùng và hệ thống ngoài bao quanh. Cho mọi người, kể cả người ngoài kỹ thuật.
2 · ContainerZoom vào hệ thống: các khối chạy được (web app, mobile, API, cơ sở dữ liệu...). Cho PM và đội kỹ thuật.
3 · ComponentZoom vào MỘT khối: các nhóm chức năng bên trong nó. Cho lập trình viên.
4 · CodeZoom vào một component: lớp/class cụ thể. Thường để công cụ tự sinh, hoặc bỏ qua.

Trông một mức C4 thế nào? Đây là sơ đồ Context của Mèo Đói (app đặt đồ ăn) - so với tấm bảng trắng hỗn loạn ở Bước 1: mỗi hộp ghi rõ loại, mỗi mũi tên có nhãn rõ hướng.

System Context - Mèo Đói

[Người dùng]

Thực khách

Đặt món, theo dõi đơn.

[Người dùng]

Tài xế

Nhận đơn và giao hàng.

[Người dùng]

Nhà hàng

Nhận đơn, chuẩn bị món.

[Hệ thống phần mềm]

Mèo Đói

Kết nối thực khách, nhà hàng, tài xế.

[Hệ thống ngoài]

Cổng thanh toán

Thu tiền đơn hàng.

[Hệ thống ngoài]

Dịch vụ Bản đồ

Định tuyến & ước tính thời gian giao.

Đặt món [HTTPS]Nhận đơn giao [HTTPS]Quản lý đơn [HTTPS]Thu tiền [API]Tính đường & ETA [API]

Trung thực

Bốn mức nghe có vẻ phải vẽ đủ bốn, nhưng không phải vậy. Phần lớn dự án chỉ cần mức 1 và 2. Mức 4 gần như luôn được bỏ qua. C4 cho bạn một thang đo chung để biết mình đang ở đâu, chứ không bắt bạn vẽ cho đủ bộ.

Lý thuyết đủ rồi - hãy tự zoom thử. Widget dưới đây có hai dự án khác nhau: Lớp Học Trực Tuyến (nền tảng học online) và Mèo Đói (app đặt đồ ăn). Bắt đầu ở mức Context, rồi bấm vào hộp có dấu 🔍 để zoom vào trong; bấm "Zoom ra" để lùi lại.

🗺️ Bản đồ kiến trúc:

Nền tảng học online: học viên xem bài, làm quiz, theo dõi tiến độ.

Mức 1 Mức 2 Mức 3

Mức 1 - System Context

System Context - Lớp Học Trực Tuyến

Học viên
Mèo con học bài, làm quiz, xem tiến độ.
Giảng viên
Soạn bài giảng, chấm bài.
Cổng thanh toán ngoài
Thu học phí.
Dịch vụ Email ngoài
Gửi email thông báo.

Quan hệ (có nhãn & hướng)

  • Học viên Lớp Học Trực Tuyến : Học & làm bài [HTTPS]
  • Giảng viên Lớp Học Trực Tuyến : Soạn bài & chấm [HTTPS]
  • Lớp Học Trực Tuyến Cổng thanh toán : Thu học phí [API]
  • Lớp Học Trực Tuyến Dịch vụ Email : Gửi email [SMTP]
  • Cùng một hệ thống, ba mức chi tiết - giống zoom bản đồ, không phải ba hệ thống khác nhau.
  • Công nghệ (như PostgreSQL, React Native) chỉ xuất hiện từ mức Container trở vào, không nhồi vào mức Context.
  • Người dùng (những chú mèo) đứng quanh rìa; mọi mũi tên đều có nhãn nêu rõ ai làm gì với ai.
  • Thử cả hai dự án: tư duy zoom giống hệt nhau, dù một bên là học online, một bên là giao đồ ăn.

Để ý cách đọc từng mức

Mức Context bạn có thể đưa cho sếp kinh doanh xem mà họ vẫn hiểu. Mức Container thì hợp cho PM và đội kỹ thuật. Mức Component dành cho lập trình viên sắp viết code trong khối đó. Cùng một mô hình, ba khán giả.

So với tấm bảng trắng hỗn loạn ở Bước 1, C4 chữa cả ba căn bệnh bằng vài quy ước đơn giản:

  • Mỗi sơ đồ chỉ ở MỘT mức zoom - hết bệnh "trộn mức trừu tượng".
  • Ít kiểu hộp, mỗi hộp ghi rõ là người / hệ thống / container / component - đỡ cần chú giải rườm rà.
  • Mọi mũi tên đều có nhãn nêu rõ hướng và ý nghĩa - hết bệnh "mũi tên mơ hồ".
  • Chọn mức theo khán giả - nên không còn cảnh một sơ đồ làm khổ mọi phòng ban.

Khoá này sẽ đi từ nền tảng tới thực hành trên nhiều dự án. Bước kế tiếp là phân biệt cho rõ hai thứ người ta hay lẫn: mô hình so với sơ đồ và bốn khái niệm nền. Sau đó ta sẽ học kỹ từng mức, bắt đầu với Level 1: System Context.

Sẵn sàng zoom

Nhớ một câu cho cả khoá: C4 là bản đồ, không phải bản vẽ kỹ thuật bắt buộc. Mục tiêu cuối là để bất kỳ ai trong công ty, ở đúng mức zoom của họ, đều hiểu hệ thống đang nói về cái gì.

Câu hỏi thường gặp

Không. C4 là cách TỔ CHỨC tư duy và sơ đồ kiến trúc theo nhiều mức zoom, độc lập với ký pháp (notation). Bạn vẫn có thể vẽ bằng UML, ArchiMate hay hộp-và-mũi-tên thường. C4 chỉ nhẹ hơn và tập trung vào giao tiếp, nên dễ phổ biến cho cả người ngoài kỹ thuật.

Không. C4 là một bộ khái niệm và cách nhìn, không phải công cụ. Bạn vẽ bằng gì cũng được: giấy, bảng trắng, draw.io, hay "diagrams as code" như Structurizr/Mermaid (sẽ học ở bài sau). Quan trọng là tư duy theo mức zoom, không phải dùng app nào.

Không. Phần lớn đội chỉ cần hai mức đầu: System Context và Container. Mức Component vẽ khi một container đủ phức tạp để cần soi vào trong; mức Code (lớp/class) hầu như được bỏ qua hoặc để công cụ tự sinh. Vẽ vừa đủ cho người đọc, đừng vẽ cho đủ bộ.

Simon Brown đề xuất C4 (khoảng năm 2011) sau nhiều năm tư vấn và dạy về kiến trúc phần mềm. Tài liệu chính thức miễn phí và súc tích tại c4model.com.

Trang chính thức: c4model.com →

KHÔNG - và đây là hiểu lầm phổ biến nhất. Container trong C4 nghĩa là một đơn vị chạy/triển khai được (một web app, một API, một cơ sở dữ liệu...), có trước Docker rất lâu. Bài "Level 2: Container" sẽ làm rõ; tạm thời chỉ cần nhớ hai chữ này khác nghĩa nhau.

Tick những điều em tự tin làm được. Càng lên cao, em càng hiểu sâu.

Tick những điều em tự tin làm được sau khi học bài này. 0/6

Trả lời vài câu để chắc rằng em đã nắm bài.

Câu 1/3 Điểm: 0

Đâu là một trong ba "căn bệnh" khiến sơ đồ kiến trúc tuỳ hứng gây hiểu lầm?

  1. 1

    Săn một sơ đồ "hỗn loạn"

    Tìm một sơ đồ kiến trúc thật (trong slide, blog, hoặc README của một dự án mã nguồn mở) và chỉ ra nó mắc "bệnh" nào trong ba bệnh ở Bước 2.

    Hoàn thành khi: Dán/chụp được sơ đồ; chỉ ra ≥2 trong 3 bệnh, mỗi bệnh kèm một ví dụ cụ thể trên sơ đồ đó.

  2. 2

    Mũi tên này nghĩa là gì?

    Lấy một sơ đồ có mũi tên không nhãn. Với 3 mũi tên bất kỳ, viết lại nhãn cho rõ: ai làm gì với ai, và (nếu hợp lý) qua giao thức nào.

    Hoàn thành khi: Đủ 3 nhãn; mỗi nhãn nêu rõ hướng và ý nghĩa, không còn mơ hồ kiểu "kết nối / liên quan".

  3. 3

    Zoom hai dự án

    Dùng widget ở Bước 5. Với mỗi dự án (Lớp Học Trực Tuyến và Mèo Đói), viết một câu mô tả mỗi mức zoom nói về cái gì.

    Hoàn thành khi: Đủ 2 dự án × 3 mức = 6 câu; mỗi câu nêu đúng nội dung mức đó (Context/Container/Component).

  4. 4

    Khán giả nào, mức nào

    Liệt kê bốn nhóm người: sếp kinh doanh, quản lý dự án (PM), lập trình viên, vận hành (ops). Gán cho mỗi nhóm mức C4 mà mèo con nghĩ là hợp nhất để trình bày.

    Hoàn thành khi: Đủ 4 nhóm; mỗi nhóm có một mức và một câu lý do ngắn.

  5. 5

    Vẽ Context cho dự án của mèo con

    Chọn một hệ thống mèo con đang dùng (app nhắn tin, app xem phim...). Vẽ tay sơ đồ System Context: hệ thống ở giữa, người dùng và các hệ thống bên ngoài bao quanh, mỗi mũi tên có nhãn.

    Hoàn thành khi: Sơ đồ có tiêu đề; có ≥1 người dùng và ≥1 hệ thống ngoài; mọi mũi tên đều có nhãn rõ hướng.

  6. 6

    Ẩn dụ bản đồ

    Bằng lời của mèo con, giải thích vì sao "bản đồ nhiều mức zoom" là cách hay để hình dung C4 (liên hệ với cách dùng Google Maps).

    Hoàn thành khi: Một đoạn ngắn nêu được: zoom ra để thấy tổng thể, zoom vào để thấy chi tiết, và mỗi mức phục vụ một mục đích/khán giả.