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

Những mẩu tin ngắn hàng ngày dành cho bạn
  • Hẳn là nhiều người ở đây đã nghe đến kiểu tấn công bảo mật Clickjacking rồi nhỉ. Kẻ tấn công thường nhúng một website (thường là mục tiêu) vào trong một iframe trên website của chúng, sau đó làm mờ hoặc ẩn nó đi rồi đặt vào vị trí các nút bấm trên web, ví dụ "Bấm vào để nhận quà". Đâu ai ngờ rằng phía trên nút bấm đó là một nút bấm khác trong iframe. Khá nguy hiểm!

    Nhưng trình duyệt đã có cách ngăn chặn kiểu tấn công này bằng các quy tắc như tiêu đề X-Frame-Options, frame-ancestors của CSP và SameSite: Lax/Strict của Cookies...

    Mới đây, đã xuất hiện thêm kiểu tấn công mới - "DoubleClickjacking" 😨. Đại ý là "hắn" lợi dụng hành động double click để lừa người dùng bấm vào một nút mà hắn muốn. Chi tiết hơn trong bài viết này: DoubleClickjacking: A New Era of UI Redressing.

    » Xem thêm
  • Mọi người đã nghe nói đến Jujutsu - jj - một dạng quản lý phiên bản cho mã nguồn (version control system) chưa? Có vẻ như nó đang nhận được nhiều sự quan tâm.

    Chờ xíu! Chẳng phải git đã quá tốt rồi sao? Thế thì chế ra thằng jj để làm gì nữa? Cũng hơi khó trả lời nhỉ? Mỗi công cụ sinh ra chắc chắn phải cải thiện hoặc khắc phục được nhược điểm của cái trước. Cho nên jj ắt hẳn phải làm được điều gì đó mà git chưa làm được nên mới nổi lên như vậy.

    Thật ra mình đã nghe nói đến jj từ vài tháng trước rồi, nhưng vào đọc thì toàn kiến thức cao siêu. Hoặc là đang mang nặng cái lối suy nghĩ của git vào trong đầu rồi nên chưa lĩnh hội ra được điều gì cả.

    Mình hay có kiểu cái gì đọc lần 1 mà không hiểu thì đọc tiếp lần 2, lần 2 không hiểu thì đọc tiếp lần 3... đến lần thứ n mà vẫn không hiểu thì bỏ. Cơ mà không phải là từ bỏ mà một thời gian sau đó quay lại đọc tiếp. Đến một lúc nào đó khả năng mình sẽ hiểu ra một ít vấn đề, thế mới tài 😆.

    Thì cái jj này có vẻ như nó đang mở ra được tính linh hoạt trong việc "cam kết" mã. Tưởng tượng bạn đang làm việc trên một dự án, đang ở nhánh này, muốn sang nhánh khác để sửa, nhưng mà lại đang viết dở ở nhánh này, thế là phải stash, rồi checkout, rồi commit, rồi merge hoặc rebase lại vào nhánh cũ... nhìn chung quá trình làm việc với git nghiêm ngặt đến mức cứng nhắc, cần nhiều thao tác để giải quyết một vấn đề, chưa kể cái cây commit (commit-tree) nữa thì ôi thôi, khỏi xem cho đỡ nhức mắt. Thế nên ông jj này đang làm cách nào đó để bạn khỏi cần phải quan tâm đến các nhánh luôn, sửa trực tiếp vào commit. Nghe ảo nhỉ 😂.

    Đấy mới lĩnh hội được đến đấy, hy vọng sau n lần đọc lại nữa mình sẽ viết được một bài chi tiết hơn về công cụ này.

    » Xem thêm
  • Gòi gòi tới công chiện gòi 🤤🤤🤤

    » 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...
Bấm hoặc cuộn mạnh để sang bài mới