de_DEen_USes_ESfa_IRfr_FRhi_INid_IDjapl_PLpt_PTru_RUvizh_CNzh_TW

掌握C4容器圖:深入探討技術選擇、責任分工與溝通(附PlantUML範例)

什麼是C4容器圖?

容器圖是第二層西蒙·布朗C4模型中的第二層。它深入探討單一軟體系統(於第一層—系統上下文定義)以顯示:

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

  • 系統邊界內架構的高階形狀架構的高階形狀。

  • 主要的可部署/可執行的單元稱為容器.

  • 各容器的技術選擇針對每個容器。

  • 容器之間以及與外部實體/系統之間如何互動互動。

重要說明:C4中的「容器」並非一定是Docker容器。它是指任何可獨立部署或執行的單元,可執行程式碼或儲存資料。範例:

  • Web應用程式 / 單頁面應用程式(SPA)

  • 行動應用程式

  • 伺服器端API / 微服務

  • 資料庫(資料結構)

  • 檔案儲存(S3儲存桶、檔案系統資料夾)

  • 訊息代理 / 佇列(當明確建模時)

  • 桌面 / CLI應用程式

  • 批次處理 / 定期工作

此圖表仍保持高階 — 不包含內部類別或程式碼細節(那是第3層元件或第4層程式碼)。

何時建立容器圖

當出現以下情況時,建立(並維護)容器圖:

  • 您已完成(或至少草擬)了系統脈絡 圖,並需要回答:「我們系統內部的主要構建模塊是什麼?」

  • 新工程師、架構師或運維人員的入職訓練——他們需要快速理解技術堆疊與高階責任。

  • 做出重大的技術或架構決策(單體系統 → 微服務、新增行動應用程式、選擇資料庫、引入訊息佇列、雲端遷移)。

  • 用於審計、合規性、安全審查或事件回應的文件記錄(有助於顯示攻擊面與資料流動)。

  • 您希望實現「架構即程式碼」,使其存於程式碼庫中並隨著系統演進。

  • 大多數團隊到此為止 — 西蒙·布朗本人指出系統脈絡 + 容器 圖對大多數軟體團隊而言已足夠。只有當容器內部的複雜性值得時,才進一步深入(元件/程式碼)。

若出現以下情況,可跳過或延後:

  • 系統極為簡單(單一程序 + 資料庫)。

  • 您處於極早期的構想階段,僅需整體脈絡。

為什麼要使用容器圖?(主要優勢)

  • 讓不同受眾清晰理解
    開發人員可看見技術與整合點。
    運維/基礎設施團隊可看見可部署單元與通訊路徑。
    架構師可看見責任邊界與技術負債風險。
    管理者可看見足夠中立但具體的視圖。

  • 避免「一張大圖」的問題
    防止將所有內容(使用者 + 基礎設施 + 類別 + 雲端圖示)塞入一張過載的圖片中。

  • 突顯關鍵決策
    清楚呈現如 SPA + API + 關聯式資料庫 vs. 伺服器端渲染 + NoSQL,或同步 vs. 事件驅動等選擇。

  • 溝通與協作
    在設計會議、事件事後分析、威脅建模和路線圖規劃期間,作為共享地圖使用。

  • 動態文件
    當以 PlantUML / Structurizr DSL 或類似語言撰寫時 → 版本控制於 Git 中,於 CI 上自動重新生成,始終保持最新。

如何創建出色的容器圖(逐步指南 + 最佳實務)

  1. 從第 1 層開始
    從上下文圖中複製人員與外部軟體系統——它們將成為與您的容器互動的參與者。

  2. 繪製系統邊界
    使用 System_Boundary 在 PlantUML 中明確界定「我們系統內部」的範圍。

  3. 識別容器
    提問:哪些是可獨立運行/部署、能提供系統功能的元件?
    常見模式:

    • Web SPA ↔ API 後端 ↔ 資料庫

    • 行動應用程式 ↔ 前端後端(BFF)↔ 共用服務

    • 具訊息中介的微服務

    • 傳統單體架構 + 新的 API 層

  4. 新增技術與簡要描述
    每個容器應顯示:名稱、技術、簡短目的。
    保持描述少於 15 個字。

  5. 定義互動(關係)
    顯示方向 + 協定 + 目的(例如:「JSON/HTTPS」、「讀取並寫入」、「發布至」、「消費自」)。
    在關係上使用動詞。

  6. 最佳實務

    • 保持可讀性 — 目標控制在少於 10–12 個容器。若超過 → 創建專注的視圖(例如:「API 子系統容器」)。

    • 保持一致 — 相同的佈局方向(自上而下/自左而右),相同的細節層級。

    • 使用圖示/角色 — 增加視覺吸引力(PlantUML 支援 devicons、font-awesome 等)。

    • 圖例與關鍵 — 在 PlantUML 中啟用自動圖例。

    • 避免雜亂 — 若佇列或主題無實際價值,則省略;改以在箭頭上標示協定。

    • 版本控制並以程式碼儲存 — 將 .puml 檔案提交至程式碼庫。

    • 針對觀眾調整 — 為開發人員提供詳細技術版本,為利害關係人提供簡化版本。

PlantUML 範例 – 傳統的網路銀行系統(Big Bank plc 風格)

以下是一個使用官方 C4-PlantUML 庫的乾淨、可投入生產的範例。

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

' 可選:加入美觀的圖示(來自 tupadr3 精靈)
!include https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons/angular.puml
!include https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons/java.puml
!include https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons/postgresql.puml
!include https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons/android.puml

title 容器圖:網路銀行系統

Person(customer, "個人銀行客戶", "Big Bank plc 的客戶")

System_Boundary(c1, "網路銀行系統") {
    Container(spa, "單頁應用程式", "JavaScript & Angular", "透過瀏覽器為客戶提供所有網路銀行功能", $sprite="angular")
    Container(mobile, "行動應用程式", "Android/iOS (React Native)", "有限的網路銀行功能", $sprite="android")
    Container(api, "API 應用程式", "Java & Spring Boot", "透過 API 提供網路銀行功能", $sprite="java")
    ContainerDb_Ext(db, "銀行資料庫", "PostgreSQL", "儲存使用者偏好、快取資料與登入狀態(核心帳戶/交易仍保留在主機系統中)", $sprite="postgresql")
}

System_Ext(core, "核心銀行系統", "主機系統 – 現有系統")
System_Ext(email, "電子郵件系統", "發送電子郵件(例如 AWS SES)")

Rel(customer, spa, "使用", "HTTPS")
Rel(customer, mobile, "使用", "HTTPS")

Rel(spa, api, "呼叫", "JSON/HTTPS")
Rel(mobile, api, "呼叫", "JSON/HTTPS")

Rel(api, db, "讀取與寫入", "JDBC/SQL")
Rel(api, core, "使用", "JSON/HTTPS")
Rel(api, email, "使用 HTTPS 發送電子郵件", "HTTPS")

LAYOUT_WITH_LEGEND()
LAYOUT_TOP_DOWN()

@enduml

此範例可呈現一個清晰的圖表,包含:

  • 系統邊界

  • 技術標籤

  • 精靈/圖示

  • 清晰的關係

  • 圖例

您可以直接將其貼入 PlantUML 在線伺服器或任何相容的 IDE/編輯器中。

請以此結構作為範本——將元件替換為您系統的名稱、技術與資料流。如需更進階的樣式(主題、自訂色彩),請參考 C4-PlantUML GitHub 上的範例。

祝您繪圖愉快——請記住:目標是有效溝通,而非 UML 的完美!

C4 容器圖資源