架构图C4 model

概述

最近在开发系统中,发现需要一种方式来构建对于当前系统的理解和细化,UML是我一下子映入脑海的方式,但是很久不再接触了,刚好在前段时间看到关于C4model(官网)相关文章,刚好可以试试

架构图的主要功能是从各个角度和各个层次去描述系统的功能,主要是从宏观到微观的描述。C4 Model也是提供图形从不同的层次去描述我们的系统。主要的优势是C4 Model提供很少的抽象图形要素和图类型来描述系统,使得各个系统参与者都能很快理解系统的功能。这些图从层级上来看都是缩放的,就行谷歌地图一样


地图

为了构建实际系统的抽象。C4 Model对于系统的描述提供了四个抽象层次:


抽象

这个抽象层次里面包含5个要素

  • Software System:软件系统最高的抽象层次,描述了交付给用户完成用户所需功能的系统。
  • Person:使用系统的人或者角色
  • Container: 容器是独立运行一些代码和数据,组合起来完成系统功能的要素。一个容器可以是Server-side web application、Client-side web application、Client-side desktop application、Mobile app、Server-side console application、Microservice、Database、Blob or content store、File system、Shell script等。
  • Component:组件一组相关功能的封装,对外提供良好的接口。

基于这四个层次的抽象,C4 Model由4张核心图和3张附加图组成

四张核心图

4张核心图分别为系统上下文图(Context)、容器图(Container)、组件图(Component)、代码图(Code),代码图是实际的类实现,可选。

系统上下文图

系统上下文图

系统上下文图主要表述的是当前要开发的系统和周边环境的关系,包括系统和用户之间的关系和系统和周边系统的关系,在系统上下文图里,方块指代的是软件系统,蓝色表示我们关注的系统(位于中心),灰色表示我们直接依赖的系统或者依赖我们的系统,虚线框一般用于用于聚合相关元素。

容器图

容器图

当我们理解了当前关注的系统在整个IT环境中的地位的时候,需要将当前系统放大,观察里面的内部结构,放大后就会看到容器,如上图所示,C4模型认为系统是由容器组成的。容器图显示的是软件架构中各个独立的部分(一般是一个独立的进程),每个容器的职责和他们间是如何交互的,以及容器与其他系统是如何交互的。它显示了当前软件系统的技术选型和交互方式。它是一个简单的、以高级技术为重点的图表,对软件开发人员和支持/操作人员都很有用

组件图

组件图

继续放大容器,可以看到每个容器里有哪些组件组成,组件的职责是什么,组件是如何交互的。组件主要是相关功能的聚合,提供对外的接口

代码图

代码图

代码图跟UML里面的类图很类似。除非非常重要的且还没有写出代码的组件才画代码图。
核心图主要固定了我们系统的抽象层次,方便讨论和理解。

三张扩展图

核心图让我理解了系统静态架构,三张扩展图,可以让我们关注更多的维度。

系统景观图

image.png

系统景观图是比系统上下文图更丰富的系统级别的表达。不像上下文图只关注聚焦系统和它的直接关系,连一些间接相关的系统都会标示出来,包括那些外部系统相关的用户。系统景观图的意义在于从企业的整个IT架构来看待当前要构建的系统的功能和价值。

动态图

动态图

动态图不同于上面所有静态图的表达,它表达的系统的某个运行态,这个运行态中完成了一个用户的场景或者功能。所以一般有步骤,有顺序。而且可以在各个层级去描述这个动态图。

部署图

部署图

部署图主要描述系统在容器级别是如何实际部署到物理基础设施中的。

图形符号(Notation)如何描述

C4模型没有规定任何特殊的图形。所以简单的图形就可以描述,如下


Notation

我们可以使用颜色和形状是的图形描述更加清晰。所有图形都需要是自描述的。
下面有一些关于图形符号的实践推荐

  • 每张图都应该有个标题标明图类型和范围
  • 图中需要有个图例来解释所使用的图形符号(比例 形状、颜色、边框样式等)
  • 图形里面的缩写所有受众都能理解

元素

  • 所有元素的类型需要被明确指定
  • 所有元素都需要一个简单描述,描述其核心职能
  • 所有的容器和组件都需要明确的指定技术

关系

  • 所有关系线都只表示单向的关系
  • 每一行都应该加上标签,标签应该与关系的方向和意图保持一致(例如依赖关系或数据流)。尽量把标签写得具体些,最好避免使用“Uses”这样的单字。
  • 容器之间的关系(通常代表进程间通信)应该有明确标记的技术/协议。

C4的工具

在挑选了众多工具之后,发现C4-PlantUML比较适合,当然功能最强大的还是C4 model官网推荐的第一个工具structurizr,但是是商业版本的。C4-PlantUML是可以用文本描述图形和图形关系,但是不足之处是支持的图并不是很全,不支持动态图和部署图。所有图形符号使用方框标示的,直观性要差一些。

安装

下载java并安装,Path里面也要有java的路径
下载graphviz并安装
下载visual studio code安装

配置graphviz的环境

找到本地graphviz的安装路径的bin目录,我的是D:\Program Files (x86)\Graphviz2.38\bin,然后配置系统变量GRAPHVIZ_DOT的值为D:\Program Files (x86)\Graphviz2.38\bin\dot.exe 就成功了

安装vscode插件

打开vscode
运行 VS Code Quick Open (Ctrl+P)
输入ext install plantuml

图形示例

系统上下文图

@startuml
!includeurl https://raw.githubusercontent.com/RicardoNiepel/C4-PlantUML/master/C4_Context.puml
' uncomment the following line and comment the first to use locally
' !include C4_Context.puml

LAYOUT_WITH_LEGEND

title System Context diagram for Internet Banking System

Person(customer, "Personal Banking Customer", "A customer of the bank, with personal bank accounts.")
System(banking_system, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")

System_Ext(mail_system, "E-mail system", "The internal Microsoft Exchange e-mail system.")
System_Ext(mainframe, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")

Rel(customer, banking_system, "Uses")
Rel_Back(customer, mail_system, "Sends e-mails to")
Rel_Neighbor(banking_system, mail_system, "Sends e-mails", "SMTP")
Rel(banking_system, mainframe, "Uses")
@enduml
系统上下文

系统景观图

@startuml
!includeurl https://raw.githubusercontent.com/RicardoNiepel/C4-PlantUML/master/C4_Context.puml
' uncomment the following line and comment the first to use locally
' !include C4_Context.puml

'LAYOUT_TOP_DOWN
'LAYOUT_AS_SKETCH
LAYOUT_WITH_LEGEND

title System Landscape diagram for Big Bank plc

Person(customer, "Personal Banking Customer", "A customer of the bank, with personal bank accounts.")

Enterprise_Boundary(c0, "Big Bank plc") {
    System(banking_system, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")

    System_Ext(atm, "ATM", "Allows customers to withdraw cash.")
    System_Ext(mail_system, "E-mail system", "The internal Microsoft Exchange e-mail system.")

    System_Ext(mainframe, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")

    Person_Ext(customer_service, "Customer Service Staff", "Customer service staff within the bank.")
    Person_Ext(back_office, "Back Office Staff", "Administration and support staff within the bank.")
}

Rel_Neighbor(customer, banking_system, "Uses")
Rel_R(customer, atm, "Withdraws cash using")
Rel_Back(customer, mail_system, "Sends e-mails to")

Rel_R(customer, customer_service, "Asks questions to", "Telephone")

Rel_D(banking_system, mail_system, "Sends e-mail using")
Rel_R(atm, mainframe, "Uses")
Rel_R(banking_system, mainframe, "Uses")
Rel_D(customer_service, mainframe, "Uses")
Rel_U(back_office, mainframe, "Uses")

Lay_D(atm, banking_system)

Lay_D(atm, customer)
Lay_U(mail_system, customer)
@enduml
系统景观图

容器图

@startuml
!includeurl https://raw.githubusercontent.com/RicardoNiepel/C4-PlantUML/master/C4_Container.puml
' uncomment the following line and comment the first to use locally
' !include C4_Container.puml

LAYOUT_TOP_DOWN
'LAYOUT_AS_SKETCH
LAYOUT_WITH_LEGEND

title Container diagram for Internet Banking System

Person(customer, Customer, "A customer of the bank, with personal bank accounts")

System_Boundary(c1, "Internet Banking") {
    Container(web_app, "Web Application", "Java, Spring MVC", "Delivers the static content and the Internet banking SPA")
    Container(spa, "Single-Page App", "JavaScript, Angular", "Provides all the Internet banking functionality to cutomers via their web browser")
    Container(mobile_app, "Mobile App", "C#, Xamarin", "Provides a limited subset of the Internet banking functionality to customers via their mobile device")
    ContainerDb(database, "Database", "SQL Database", "Stores user registraion information, hased auth credentials, access logs, etc.")
    Container(backend_api, "API Application", "Java, Docker Container", "Provides Internet banking functionality via API")
}

System_Ext(email_system, "E-Mail System", "The internal Microsoft Exchange system")
System_Ext(banking_system, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")

Rel(customer, web_app, "Uses", "HTTPS")
Rel(customer, spa, "Uses", "HTTPS")
Rel(customer, mobile_app, "Uses")

Rel_Neighbor(web_app, spa, "Delivers")
Rel(spa, backend_api, "Uses", "async, JSON/HTTPS")
Rel(mobile_app, backend_api, "Uses", "async, JSON/HTTPS")
Rel_Back_Neighbor(database, backend_api, "Reads from and writes to", "sync, JDBC")

Rel_Back(customer, email_system, "Sends e-mails to")
Rel_Back(email_system, backend_api, "Sends e-mails using", "sync, SMTP")
Rel_Neighbor(backend_api, banking_system, "Uses", "sync/async, XML/HTTPS")
@enduml
容器图

组件图

@startuml
!includeurl https://raw.githubusercontent.com/RicardoNiepel/C4-PlantUML/master/C4_Component.puml
' uncomment the following line and comment the first to use locally
' !include C4_Component.puml

LAYOUT_WITH_LEGEND

title Component diagram for Internet Banking System - API Application

Container(spa, "Single page Application", "javascript and angular", "Provides all the internet banking functionality to customers via their web browser.")
Container(ma, "Mobile App", "Xamarin", "Provides a limited subset ot the internet banking functionality to customers via their mobile mobile device.")
ContainerDb(db, "Database", "Relational Database Schema", "Stores user registration information, hashed authentication credentials, access logs, etc.")
System_Ext(mbs, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")

Container_Boundary(api, "API Application") {
    Component(sign, "Sign In Controller", "MVC Rest Controlle", "Allows users to sign in to the internet banking system")
    Component(accounts, "Accounts Summary Controller", "MVC Rest Controlle", "Provides customers with a summory of their bank accounts")
    Component(security, "Security Component", "Spring Bean", "Provides functionality related to singing in, changing passwords, etc.")
    Component(mbsfacade, "Mainframe Banking System Facade", "Spring Bean", "A facade onto the mainframe banking system.")

    Rel(sign, security, "Uses")
    Rel(accounts, mbsfacade, "Uses")
    Rel(security, db, "Read & write to", "JDBC")
    Rel(mbsfacade, mbs, "Uses", "XML/HTTPS")
}

Rel(spa, sign, "Uses", "JSON/HTTPS")
Rel(spa, accounts, "Uses", "JSON/HTTPS")

Rel(ma, sign, "Uses", "JSON/HTTPS")
Rel(ma, accounts, "Uses", "JSON/HTTPS")
@enduml
组件图
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容