C4模型的软件架构图


该存储库是使用 C4 模型创建软件架构图的示例。

图表应该易于创建和更新,确保每个人都能获得最新的信息

我们都经历过加入一个复杂的项目,解读代码库就像读一整本小说一样。工程师是代码奇才,但即使是最好的工程师也会迷失在杂乱无章的代码中。挑战在于架构图(如果存在的话)通常是过去时代的过时遗物。

这就是为什么创建和维护清晰的图表应该毫不费力。最新的视觉效果可确保每个人都在同一页面上,从而消除混乱和浪费时间。

C4 模型
C4 模型的创建是为了帮助软件开发团队描述和交流软件架构。

C4 代表“上下文、容器、组件和代码”。
这四个层次足以描述一个复杂的系统。

解释这一概念的最佳方式是思考我们如何使用 Google 地图。当我们在 Google 地图上探索某个区域时,我们通常会先缩小地图以帮助我们了解背景信息。一旦我们找到我们感兴趣的大致区域,我们就可以放大地图以获得更多细节。

第一级:Context背景
这一层级是最为缩小的,它是系统在世界背景下的鸟瞰图。该图集中于参与者和系统。

 Context图:该图描绘了任务管理软件系统与外部系统以及使用它的不同用户组的交互。

第 2 级:容器
容器级别是系统的更详细视图(不要将 C4 容器与 Docker 容器混淆)。

它揭示了各种功能单元(如应用程序和数据库)如何协同工作并分配职责。此外,该图还突出显示了所采用的关键技术并展示了这些容器之间的通信流程。它以技术为中心的简化视图展示了系统的核心组件及其交互。

如果您有微服务架构,那么每个微服务都将是一个容器。

容器的示例包括:

  • 单页应用程序
  • 网络服务器
  • 无服务器函数
  • 数据库
  • API
  • 消息总线
  • ETC。

容器图

本章深入探讨任务管理软件系统的内部组成。它展示了组成系统的各种容器(例如用户界面、数据存储)及其交互方式。


第 3 级:组件
下一个放大级别是组件。这显示了应用程序的主要结构构建块,通常是应用程序的概念视图。这里的组件一词比较宽泛。它可以表示控制器或包含业务逻辑的服务。

该图重点介绍任务管理软件系统中 API 容器的内部结构。它表明 API 容器包含关键功能,例如用于数据操作和用户身份验证机制的 CRUD 操作(创建、读取、更新、删除)。

第四级:代码
最深层次的缩放是代码图。虽然存在此图,但由于代码描绘的画面非常相似,因此通常不使用。


补充图表
除了以上 4 张图之外,还有一些值得一提的:

  • 部署图
  • 动态图:描述过程或流程


图表即代码
C4 的强大之处在于它采用了图表即代码的方法,这意味着您可以将图表视为代码库:

  • 版本控制:将它们存储在源代码控制系统(如 Git)中,以便于跟踪和协作。
  • 协作:使用拉取请求共同处理图表,类似于代码审查。
  • 自动化:将它们集成到您的构建管道中,以便使用您喜欢的工具进行自动渲染。

有一些工具可以帮助进行建模和绘图,但是现在最流行的是带有自定义 DSL(领域特定语言)的Structurizr 。
你只需要熟悉 DSL 语法,它非常简单。只要你习惯了,你就能立即创建或更新图表。
下面您可以看到我们的任务管理软件系统的缩短的 DSL。
workspace {
    model {
        # Actors
        customer = person "Customer" "" "person"
        admin = person
"Admin User" "" "person"

        # External systems
        emailSystem = softwareSystem
"Email System" "Mailgun" "external"
        calendarSystem = softwareSystem
"Calendar System" "Calendly" "external"

        # Task Management System
        taskManagementSystem  = softwareSystem
"Task Management System"{
            webContainer = container
"User Web UI" "" "" "frontend"
            adminContainer = container
"Admin Web UI" "" "" "frontend"
            dbContainer = container
"Database" "PostgreSQL" "" "database"
            apiContainer = container
"API" "Go" {
                authComp = component
"Authentication"
                crudComp = component
"CRUD"
            }
        }

        # Relationships (Actors & Systems)
        customer -> webContainer
"Manages tasks"
        admin -> adminContainer
"Manages users"
        apiContainer -> emailSystem
"Sends emails"
        apiContainer -> calendarSystem
"Creates tasks in Calendar"

        # Relationships (Containers)
        webContainer -> apiContainer
"Uses"
        adminContainer -> apiContainer
"Uses"
        apiContainer -> dbContainer
"Persists data"

        # Relationships (Components & Containers)
        crudComp -> dbContainer
"Reads from and writes to"
        webContainer -> authComp
"Authenticates using"
        adminContainer -> authComp
"Authenticates using"
    }
}


在 CI 中自动渲染
由于我们可以在 Github 上托管我们的模型,因此可以非常轻松地使用您选择的工具自动化渲染图表的流程。

在我们的案例中,Structurizr 有一个 Github Action,允许您运行structurizr-cli ,这是一个 Structurizr 的命令行实用程序,可让您使用文本领域特定语言 (DSL) 基于 C4 模型创建软件架构模型。

我们的示例存储库包含一个工作流程,它只是生成一个静态页面并将其发布到 Github Pages。

name: Deploy static content to Github Pages

on:
  push:
    branches: ["main"]

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group:
"pages"
  cancel-in-progress: false

jobs:
  build:
    runs-on: ubuntu-latest
    container:
      image: ghcr.io/avisi-cloud/structurizr-site-generatr
      options: --user root
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Create site
        run: |
          /opt/structurizr-site-generatr/bin/structurizr-site-generatr generate-site -w diagram.dsl
      - uses: actions/upload-artifact@v3
        with:
          name: website
          path: build/site
  deploy:
    needs: build
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v3
        with:
          name: website
          path: build/site
      - name: Setup Pages
        uses: actions/configure-pages@v3
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v1
        with:
          path:
"build/site"
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v2

资源