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"!

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).

banner

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:

banner

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:

banner

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.

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.
Author

Xin chào, tôi tên là Hoài - một anh Dev kể chuyện bằng cách viết ✍️ và làm sản phẩm 🚀. Với nhiều năm kinh nghiệm lập trình, tôi đã đóng góp một phần công sức cho nhiều sản phẩm mang lại giá trị cho người dùng tại nơi đang làm việc, cũng như cho chính bản thân. Sở thích của tôi là đọc, viết, nghiên cứu... Tôi tạo ra trang Blog này với sứ mệnh mang đến những bài viết chất lượng cho độc giả của 2coffee.dev.Hãy theo dõi tôi qua các kênh LinkedIn, Facebook, Instagram, Telegram.

Bạn thấy bài viết này có ích?
Không

Bình luận (0)