C4 Model là gì? Một bức tranh hệ thống có thể "zoom"!

C4 Model là gì? Một bức tranh hệ thống có thể "zoom"!

Tin ngắn hàng ngày dành cho bạn
  • Đợt trước có nhắc đến openai/codex - một dạng agent nhưng chạy trong Terminal rất tiện lợi đến từ nhà OpenAI, đặc biệt đây là mã nguồn mở và đến nay họ đã hỗ trợ thêm các nhà cung cấp khác thay vì chỉ sử dụng model chatgpt như trước.

    Mới đây Anthropic cũng đã giới thiệu Claude Code gần như Codex, chỉ có điều không phải là mã nguồn mở và buộc phải sử dụng API của họ. Vì không có tiền trải nghiệm nên chỉ nghe nói dân trình khen nó quá trời, có khi còn bá hơn cả Cursor. Đổi lại là nguy cơ cháy ví bất kỳ lúc nào 😨

    » Xem thêm
  • Từ lâu rồi suy nghĩ làm thế nào để tăng sự hiện diện thương hiệu, cũng như người dùng cho blog. Nghĩ đi nghĩ lại thì chỉ có cách chia sẻ lên mạng xã hội hoặc trông chờ họ tìm kiếm, cho đến khi...

    In cái áo này được cái tắc đường khỏi phải lăn tăn, càng đông càng vui vì hàng trăm con mắt nhìn thấy cơ mà 🤓

    (Có tác dụng thật nha 🤭)

    » Xem thêm
  • Một vòng của sự phát triển nhiều dự án khá là thú vị. Tóm tắt lại trong 3 bước: Thấy một cái gì đó phức tạp -> Làm cho nó đơn giản đi -> Thêm thắt tính năng cho đến khi nó phức tạp... -> Quay trở lại vòng lặp mới.

    Tại sao lại như vậy? Để mình lấy 2 ví dụ cho các bạn thấy.

    Markdown ra đời với mục tiêu tạo ra một định dạng văn bản thô "dễ viết, dễ đọc, dễ dàng chuyển thành một dạng gì đó như HTML". Vì thời đó chẳng ai đủ kiên nhẫn mà vừa ngồi viết vừa thêm định dạng cho văn bản hiển thị ở trên web như thế nào. Ấy vậy mà giờ đây người ta đang "nhồi nhét" hoặc tạo ra các biến thể dựa trên markdown để bổ sung thêm nhiều định dạng mới đến mức... chẳng nhớ nổi hết cú pháp.

    React cũng là một ví dụ. Từ thời PHP, việc khát khao tạo ra một cái gì đó tách biệt hẳn giao diện người dùng và phần xử lý logic chính của ứng dụng thành 2 phần riêng biệt cho dễ đọc, dễ viết. Kết quả là các thư viện UI/UX phát triển rất mạnh mẽ, mang lại khả năng tương tác với người dùng rất tốt, còn phần logic ứng dụng thì nằm ở một máy chủ riêng biệt. Bộ đôi Front-end, Back-end cũng từ đấy mà thịnh hành, không thể thiếu anh bồi bàn REST API. Ấy vậy mà giờ đây React trông cũng không khác biệt gì so với PHP là mấy, kéo theo là cả Vue, Svelte... lại cùng quy tất cả về một mối.

    Cơ mà không phải vòng lặp là xấu, ngược lại vòng lặp này mang tính tiến hoá nhiều hơn là "cải lùi". Nhiều khi lại tạo ra được cái hay hơi cái cũ thế là người ta lại dựa trên cái hay đó để tiếp tục lặp. Nói cách khác là chắc lọc tinh hoa từng tí một tí một á 😁

    » Xem thêm

Vấn đề

Lần gần đây nhất mà bạn viết tài liệu cho hệ thống hoặc một chức năng là khi nào? Có sử dụng hình ảnh hay biểu đồ nào để mô tả lại cách hoạt động của nó không? Vâng, ý tôi là mấy cái biểu đồ hoạt động, tuần tự... để mô mình hoá lại luồng hoạt động của chương trình. Việc quy chuẩn luồng hoạt động theo biểu đồ đã đóng vai trò rất lớn trong quá trình diễn đạt ý nghĩa. Vì nếu như ai cũng học, cũng biết thì chỉ cần nhìn vào ai cũng hiểu.

Thông thường, các biểu đồ mô tả hoạt động của chương trình là đủ tốt, nhưng chỉ ở mức độ chức năng. Có nghĩa là chức năng đó hoạt động như thế nào, các bước thực hiện và điều gì xảy ra ở từng trường hợp... Nếu nhìn kỹ, nó chẳng khác gì logic của những dòng mã vậy. Nhưng thay vì là ngôn ngữ lập trình, thì ở đây chúng ta mô tả thông qua biểu đồ.

Hãy phóng to bức tranh lên một chút, thực tế là một hệ thống thông tin hay một hệ thống phần mềm ứng dụng không đơn giản chỉ gói gọn trong các hành động, mà còn thể hiện thông qua mối liên kết giữa các dịch vụ. Điều này thể hiện rõ nhất trong mô hình Microservices - nơi mà nhiều hệ thống nhỏ cùng tham gia vào bức tranh của một hệ thống lớn. Mà tôi tin chắc rằng, nhiều khi bạn còn chẳng hình dung ra nổi nó đang có những gì, liên kết với nhau như thế nào.

Vậy làm thế nào để thể hiện được bức tranh đó?

C4 Model

Khi tham gia vào môi trường làm việc mới gần đây nhất. Biểu đồ C4 (C4 Model) gần như là một trong những thứ đầu tiên được biết đến trong quá trình chuyển giao công việc. Nó là một bản vẽ thể hiện sự liên kết trong và ngoài hệ thống. Cụ thể là hệ thống bao gồm những cái gì? Liên kết với nhau như thế nào. Từ đó cũng cấp cho mình một cái nhìn trực quan về những thứ mà mình sắp phải đụng đến.

Bạn đọc sẽ nhận ra vẽ một sơ đồ như trên không có gì khó khăn cả. Giờ đây có rất nhiều công cụ hỗ trợ vẽ biểu đồ từ online cho đến offline bằng phần mềm cài vào máy tính. Sử dụng các hình khối đơn giản như ô vuông, hình tròn, hình con thoi... đại diện cho một dịch vụ, rồi sử dụng các mũi tên nét liền hoặc đứt nối chúng lại với nhau thế là xong. Sự thật đúng là như thế, tôi cũng nghĩ như các bạn cho đến khi C4 xuất hiện. Thế tóm lại, C4 có tác dụng gì?

Là để mọi người có một ngôn ngữ chung trong việc đọc các mô hình hệ thống. Các hình vẽ mà tôi và bạn sử dụng trong sơ đồ ở trên là không sai, chỉ có điều nó chưa được quy chuẩn. Bây giờ thử tưởng tượng điều đầu tiên khi tiếp nhận một hệ thống mới là hỏi "Anh/chị có mô hình C4 không?". Câu trả lời là "Có", thì chẳng phải mọi thứ sẽ dễ dàng hơn rất nhiều sao.

Mô hình C4 là một cách tiếp cận để mô tả kiến trúc phần mềm thông qua 4 mức độ chi tiết khác nhau, giúp các thành viên trong nhóm phát triển và các bên liên quan khác dễ dàng hiểu được kiến trúc của hệ thống. C4 là viết tắt của 4 thành phần Context (Ngữ cảnh), Container (Thùng chứa), Component (Thành phần), Code (Mã nguồn).

C4 model

Hãy tưởng tượng C4 như một bức tranh có thể "zoom". Trong đó bề mặt là lớp Context - Nơi hệ thống của chúng ta (tạm gọi là A) làm trung cùng các hệ thống liên kết bên ngoài. Khi "zoom" vào A, sẽ tiến vào lớp Container - Mô tả các thùng chứa (containers) mà A bao gồm. Container có thể là các ứng dụng web, cơ sở dữ liệu, dịch vụ microservices... mỗi cái như vậy tạm gọi là B. Như vậy trong A sẽ có rất nhiều B.

Khi "zoom" tiếp vào một B bất kỳ, ta sẽ vào lớp Component - Mô tả các thành phần bên trong mỗi container. Thành phần là các phần chức năng nhỏ hơn, như các lớp, mô-đun, hoặc dịch vụ cụ thể... tạm gọi là C. Và cuối cùng "zoom" vào C, là lớp Code - Chi tiết ở mức độ thấp nhất, mô tả cấu trúc mã nguồn.

Tóm lại, từ A cung cấp một cái nhìn toàn cảnh, khi "zoom" vào thì nhìn thấy rất nhiều B, mỗi B thì thấy rất nhiều C và tương tự mỗi C thì thấy đến tận mã nguồn. Điều đó tạo ra một biểu đồ phân cấp và càng đi sâu vào thì càng thấy được mức độ chi tiết của hệ thống.

Để hiểu rõ hơn về 4 cấp, bạn đọc nên tham khảo The C4 model for visualising software architecture.

Từ đó có thể thấy C4 cung cấp một bức tranh toàn cảnh, nếu muốn đi sâu vào phần nào thì chỉ cần "zoom" vào phần đó, chúng ta sẽ biết được bên trong có những gì và tương tác với nhau như thế nào. Giúp việc đọc hiểu, thông tin cũng minh bạch.

Vậy thì vẽ C4 như thế nào?

Một lần nữa cách tốt nhất vẫn là nên tham khảo The C4 model for visualising software architecture. Vì đây là trang web của người sáng tạo ra C4. Nhưng tóm tắt lại là hãy vẽ từng lớp!

Cần dành thời gian để hiểu và xác định đúng các thành phần trong mỗi lớp. Để làm được điều đó, bạn đọc nên dành thời gian đọc thêm Frequently asked questions. Các câu hỏi thường gặp chứa hầu hết các trường hợp mà người dùng mới bắt đầu cảm thấy khó khăn.

Thông thường, càng đi vào lớp trong thì độ phức tạp và chi tiết lại càng tăng cao, điều đó tốn khá nhiều thời gian để hoàn thành một sơ đồ C4 hoàn chỉnh, chưa kể trong quá trình phát triển, mã nguồn có thể thay đổi liên tục vậy nên điều quan trọng là xác định dự án cần chi tiết đến mức nào? Vì không nhất thiết phải đủ cả 4 lớp thì biểu đồ mới hoạt động. Lấy ví dụ, nếu chỉ muốn cung cấp một cái nhìn toàn cảnh trong thời gian ngắn thì lớp Context và Container đã vừa đủ.

C4 có hẳn một ngôn ngữ riêng để vẽ biểu đồ là structurizr.com. Thay vì sử dụng công cụ kéo thả để vẽ hình bạn có thể viết mã để tạo thành biểu đồ. Phương pháp này hơi cực lúc đầu nhưng về sau chỉnh sửa biểu đồ sẽ dễ hơn khi chỉ cần sửa mã thì hình ảnh lại được sinh ra tự động.

Nếu muốn "tiền tươi thóc thật", thử xem mã mình viết tạo ra sơ đồ như thế này thì bạn truy cập vào https://www.structurizr.com/dsl.

Trước khi kết thúc bài viết, tôi sẽ thực hành vẽ lại mô hình C4 của trang web 2coffee.dev, nhưng thời gian có hạn nên xin phép dừng ở lớp 2 thôi nhé 😅. Chủ yếu để sau khi xem xong, bạn có hình dung được hệ thống đang có gì không.

Đầu tiên là lớp Context, xác định bức tranh toàn cảnh của hệ thống thì hệ thống 2coffee sẽ gồm có Độc giả, có Hệ thống của 2coffee.dev và một bên dịch vụ khác là Turso - cơ sở dữ liệu dạng serverless.

workspace {

    model {
        user = person "Readers" "Độc giả"
        softwareSystem = softwareSystem "Blog" "2coffee.dev"
        tursoDB = softwareSystem "Turso" "SQLite Turso Database"

        user -> softwareSystem "Uses"
        softwareSystem -> tursoDB "CURD"
    }

    views {
        systemContext softwareSystem "SystemContext" {
            include *
            autoLayout
        }
        
        styles {
            element "Person" {
                color #ffffff
                background #08427b
                fontSize 22
                shape Person
            }
            element "Software System" {
                background #1168bd
                color #ffffff
            }
        }
    }
}

Mã trên tạo ra hình ảnh:

2coffee.dev context

Lớp thứ 2 là Container, xác định các thành phần bên trong hệ thống. 2coffee sử dụng Fresh - đây là một framework hoạt động theo kiểu Sever Side Render và còn viết được cả API. Thế nên các container chính gồm có Web Application (là mã nguồn chính của chương trình), phần SSR và phần API Server.

workspace {

    model {
        user = person "Readers" "Độc giả"
        softwareSystem = softwareSystem "Blog" "2coffee.dev" {
            webApplication = container "Web Application" "Mã nguồn máy chủ tại Deno deploy"
            serverSideRender = container "Server Side Render" "SSR"
            apiServer = container "apiServer" "API"
        }
        tursoDB = softwareSystem "Turso" "SQLite Turso Database"

        user -> softwareSystem "Uses"
        softwareSystem -> tursoDB "CURD"
        
        # relationships to/from containers
        user -> webApplication "Truy cập 2coffee.dev" "HTTPS"
        user -> serverSideRender "Xem trang web"
        webApplication -> serverSideRender "Render trang web"
        user -> serverSideRender "Xem / Đăng nhập / Bình luân"
        serverSideRender -> apiServer "Tương tác" "JSON/HTTPS"
        apiServer -> serverSideRender "Trả về kết quả"
        serverSideRender -> tursoDB "CURD" "JSON/HTTPS"
        apiServer -> tursoDB "CURD" "JSON/HTTPS"
    }

    views {
        systemContext softwareSystem "SystemContext" {
            include *
            autoLayout
        }
        
        container softwareSystem "Containers" {
            include *
            autoLayout
        }
        
        component webApplication "Components" {
            include *
            autoLayout
        }
        
        styles {
            element "Person" {
                color #ffffff
                background #08427b
                fontSize 22
                shape Person
            }
            element "Software System" {
                background #1168bd
                color #ffffff
            }
            element "Container" {
                background #438dd5
                color #ffffff
            }
        }
    }
    
}

Sơ đồ tạo ra giống như sau:

2coffee.dev container

Học cú pháp của structurizr tương đối nhanh vì nó có nhiều ví dụ tại Big Bank plc - Internet Banking System. Ngoài ra, cái khó là phải bóc tách được hệ thống cũng như xác định được thành phần trong các lớp cùng với độ chi tiết của mỗi lớp.

Cao cấp
Hello

Bí mật ngăn xếp của Blog

Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!

Là một lập trình viên, bạn có tò mò về bí mật công nghệ hay những khoản nợ kỹ thuật về trang blog này? Tất cả bí mật sẽ được bật mí ngay bài viết dưới đây. Còn chờ đợi gì nữa, hãy bấm vào ngay!

Xem tất cả

Đăng ký nhận thông báo bài viết mới

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.

Bình luận (0)

Nội dung bình luận...