hi,我是熵减,见字如面。

对于软件开发团队来说,写软件设计文档,花架构图,是日常工作中的关键一项。

而其中,如何画好系统设计的架构图呢? Simon Brown 就 提出 C4 模型,来解决这个问题。

基于C4模型的脚手架,架构师们就可以统一团队内的不同层级的视角,交付一个成体系的架构设计。

下面具体看一下C4模型吧。

什么是C4模型?

C4 模型是一种轻量级的软件架构图的表示法,旨在帮助团队更好地理解和沟通软件架构设计。

C4代表了四个层次的抽象化,即:

  • 上下文(Context):上下文层次主要描述了软件系统与外部系统或人员之间的交互关系,其目的是为了提供软件系统的背景和整体结构。
  • 容器(Container):容器层次描述了软件系统中的容器(如服务器、数据库等)以及它们之间的关系,其目的是为了提供软件系统内部的大体结构。
  • 组件(Component):组件层次描述了容器内的组件(如Web应用程序、服务、数据库架构等)以及它们之间的关系,其目的是为了更细致地了解软件系统的内部组成。
  • 代码(Code):代码层次描述了组件内的代码实现,其目的是为了帮助开发者更好地了解组件的实现和技术细节。

如上图所示,这四个层次对应着从高到低的不同的抽象程度。对应到软件系统中来说,就是能够从不同的层级视图上,展示软件的架构,使得设计者和开发者们可以更好地理解、交流架构设计,并推进架构的演进升级。

第1级:系统上下文图

系统上下文图是软件系统设计的起点,是让你后退一步以看到大的视角。

画一个图表,将你的系统显示为中心的一个盒子,周围是展现的主要是两类信息:

  • 本系统的用户是谁;
  • 本系统如那些外部系统有交互。

细节在这里并不重要,因为这是你缩小的视图,显示了系统全景的大图。重点应该放在人(参与者、角色、角色等)和软件系统上,而不是技术、协议和其他低级细节上。这是一种可以展示给非技术人员的图表。

  • 呈现范围:单个软件系统。
  • 主要元素:范围内的软件系统。
  • 支持元素:在范围内直接连接到软件系统的人员(例如用户、参与者、角色或角色)和软件系统(外部依赖项)。通常,这些其他软件系统位于您自己的软件系统的范围或边界之外,您对它们没有责任或所有权。
  • 目标受众:每个人,包括技术人员和非技术人员,软件开发团队内外的人员。
  • 注意:推荐推荐给大多数团队。

第2级:容器图

此处的容器,不是指Docker的一个容器。

而是类似于服务器端web应用程序、单页应用程序、桌面应用程序、移动应用程序、数据库模式、文件系统等。

本质上,容器是一个单独的可运行/可部署单元(例如,一个单独的进程空间),用于执行代码或存储数据。

系统上下文图将本系统看作一个黑盒,那么容器图则是把这个黑盒打开,深入到了软件的内部,展示了软件内体系结构的高级形状,以及职责如何在其中分布。

它还展示了主要的技术选择以及容器之间如何通信。

这是一个简单的、以技术为重点的高级图表,对软件开发人员和支持/操作人员都很有用。

  • 呈现范围:单个软件系统。
  • 主要元素:范围内软件系统中的容器。
  • 支持元素:直接连接到容器的人员和软件系统。
  • 目标受众:软件开发团队内外的技术人员;包括软件架构师、开发人员和操作/支持人员。
  • 注意:推荐推荐给大多数团队,该图没有说明部署场景、集群、复制、故障转移等。

第3级:组件图

组件图,则是进一步放大并分解了每一个容器,

接下来,您可以放大并进一步分解每个容器,以识别容器内的主要结构构建块,及其互相之间的交互关系。

组件图展示了容器是如何由许多“组件”组成的,每个组件是什么,它们的职责和技术/实现细节等。

  • 呈现范围:单个容器。
  • 主要元素:范围内容器中的组件。
  • 支持元素:容器(在软件系统范围内)加上直接连接到组件的人员和软件系统。
  • 目标受众:软件架构师和开发人员。
  • 注意:不推荐给大多数团队,如果你觉得组件图增加了价值,那么只创建组件图,并考虑为长期存在的文档自动化创建组件图。

第4级:代码结构图

如果需要深入到组件代码层面,代码结构图可以显示组件是如何作为代码来实现的。主要是使用使用UML类图、实体关系图或类似的方法。

理想情况下,这种底层细节的图表,将使用工具(例如IDE或UML建模工具)自动生成,应该考虑只显示那些,你想要重点关注的属性和方法。

所以,除了最重要或最复杂的组件之外,不建议使用这种详细级别。

  • 呈现范围:单个组件。
  • 主要元素:组件作用域中的代码元素(例如类、接口、对象、函数、数据库表等)。
  • 目标受众:软件架构师和开发人员。
  • 注意:不推荐用于大多数团队,对于长期存在的文档,大多数IDE工具都可以按需生成这种级别的详细信息。

使用C4模型的6个注意点

在团队架构中,使用C4模型来呈现架构视图时,需要注意以下几点:

  • 目标清晰:在绘制C4模型之前,应该明确需要建模的系统、软件或架构的目标。确保每个层次上的图表都有明确的目的,能够传达给观众或其他利益相关者有关系统或软件的信息。

  • 约定标识符:在绘制C4模型时,应使用一致的标识符来命名和标识不同的元素,例如系统、容器、组件和代码等。这有助于提高模型的可读性和理解性。

  • 简单明了:C4模型强调简洁、清晰的表述。在绘制C4模型时,应避免使用过多的细节或技术语言,以确保每个层次上的图表都易于理解。

  • 易于更新:C4模型应该能够随着时间的推移而更新,以反映系统或软件架构的演变。在绘制C4模型时,应该考虑如何使其易于维护和更新。

  • 适度细节:在绘制C4模型时,应考虑到每个层次上需要展示多少细节。如果图表过于复杂,可能会导致人们难以理解和使用。

  • 迭代性:C4模型是一个迭代的过程。在实践中,您可能需要多次绘制和修改C4模型以满足需求,并使其更好地反映系统或软件架构。

总之,C4模型是一种简单但强大的建模方法,可以帮助您建立清晰、易于理解和易于维护的软件架构图表。通过遵循上述建议,您可以更好地使用C4模型来设计和描述复杂的软件系统。

实践中常见的6个误区

在使用C4模型时,可能会遇到一些常见的误区。

以下是一些常见的误区,以及如何避免这些问题的方法:

  • 过度关注细节:C4模型旨在提供一个高层次的概述,以帮助人们理解系统或软件架构。因此,过度关注细节可能会使模型过于复杂,难以理解。建议在模型的每个层次上保持适度的细节,以便读者可以轻松理解。

  • 忽略系统间的交互:C4模型强调系统的上下文视图,但有时候人们可能会忽略系统之间的交互。在建模时,应该考虑系统之间的交互以及它们如何在软件架构中发挥作用。

  • 忽略时间和演变:C4模型应该是可演化的,这意味着模型应该能够反映软件架构的演变。在建模时,应该考虑如何使模型易于更新和维护,以便反映软件架构的演变。

  • 与UML混淆:虽然C4模型和UML有些相似之处,但它们是不同的建模方法。C4模型的重点是软件架构,而UML的重点是面向对象的编程。因此,建议不要将C4模型与UML混淆。

  • 未充分考虑受众:C4模型的目的是使软件架构易于理解。因此,在绘制模型时,应该考虑模型的受众群体,并为他们提供足够的上下文信息和详细说明。

  • 忽略安全和性能:在建模软件架构时,应该考虑安全和性能方面的因素。这些因素对系统的设计和实现都有重要影响,因此应该在C4模型中考虑它们。

总之,避免这些常见的误区,可以在你的软件架构建模工作中,让C4模型更好的发挥作用。

写在最后

C4模型的架构设计的脚手架,值得推荐的关键:就是其为架构设计图,提供了一个分层的清晰的结构规范。

一份可视化的 C4 模型 架构视图,可以让团队内的人,从不同层面上入手,快速到找到自己关注的要点,这是非常有利于团队内对系统设计的沟通的。

参考资料:

  1. https://c4model.com/
  2. https://www.workingsoftware.dev/software-architecture-documentation-the-ultimate-guide/

C4模型,架构设计图的脚手架,你值得拥有的更多相关文章

  1. C4 模型 - 可视化架构设计

    前言 世界上最难的两件事是: 1. 把我的思想放进你的脑袋 2. 把你的钱放进我的口袋 第二点我们不探讨,因为这是众所周知的,不信?过来试试:) 对于第一点,对我们程序员来说,其实也是我个人一直强调的 ...

  2. 京东云开发者|软件架构可视化及C4模型:架构设计不仅仅是UML

    软件系统架构设计的目标不在于设计本身,而在于架构设计意图的传达.图形化有助于在团队间进行高效的信息同步,但不同的图形化方式需要语义一致性和效率间实现平衡.C4模型通过不同的抽象层级来表达系统的静态结构 ...

  3. 软件架构系列一:C4模型

    本文要点预览:因为软件系统的分布式特点以及开发团队的分布性,了解软件架构的基础变得越来越重要.而在过度设计和毫无设计之间,我们应该把注意力放在对软件系统有重大影响的决策和权衡上.好的架构师应该是团队的 ...

  4. 工程能力之C4模型

    概述 刚在InfoQ上看到一篇介绍C4Model的文章,觉得这个模型设计的很赞,很有指导意义,做个简单的记录. Why,为什么需要架构图? ThoughtWorks中国 文章中有几句话我觉得很有道理, ...

  5. 西蒙布朗-C4模型

    关于 C4 模型的一些解释 C4 模型是来自 software architecture for developers 一书的定义,指的是 Context 上下文场景.Container 容器.Com ...

  6. linux块设备模型架构框架

    Linux块设备的原理远比字符设备要复杂得多,尽管在linux这一块的方法论有很多相似之处,但考虑到它是用中块结构,它常常要搭配内存页管理,页缓冲块缓冲来改善硬盘访问的速度,按照块硬件最大的性能要求进 ...

  7. Node实现简单的注册时后端的MVC模型架构

    实现一个简单的注册界面后端MVC模型架构 第一步:在生成的express框架的app.js中添加一个路由,代码如下:var api = require('./routes/api'); app.use ...

  8. 基于Wiki的知识共享平台模型架构

    一.引言 当今的全球化知识经济社会中呈现出信息泛滥和知识更新周期短的现象,知识管理逐渐成为现代企业管理中不容忽视的一环.虚拟企业是基于共识目标而组成的动态协作组织,成员参与的流动性与各成员之间地域分布 ...

  9. 【tornado】系列项目(一)之基于领域驱动模型架构设计的京东用户管理后台

    本博文将一步步揭秘京东等大型网站的领域驱动模型,致力于让读者完全掌握这种网络架构中的“高富帅”. 一.预备知识: 1.接口: python中并没有类似java等其它语言中的接口类型,但是python中 ...

  10. django中根据模型生成页面的脚手架app-groundwork

    相信做过Asp.net MVC的朋友对在此框架下,根据模型自动生成浏览,编辑,查看,删除的四个页面的脚手架功能记忆尤新,那么我们在用python中的django框架时,有没有此脚手架功能呢,很显然,默 ...

随机推荐

  1. springcloudgateway学习

    API网关 大型项目开发过程中,往往都是由各个不同的微服务组成的,服务可能分布在不同地区不同机房,那用户如何知道访问某服务的时候该服务的实际地址呢,这时候就需要API网关了 API 网关就像服务的门面 ...

  2. <五>function的实现原理

    类模版std::function是一种通用.多态的函数封装.std::function的实例可以对任何可以调用的目标实体进行存储.复制.和调用操作,这些目标实体包括普通函数.Lambda表达式.函数指 ...

  3. redis集合 实现 队列

    先说一下需求:用队列解决 流量削峰,主要应用场景:商城秒杀功能. 以下是业务流程图可以参考一下: 然后本地实现思路 截图下单页面 每次购买数量会减少1,设置了1000个库存,用户id 是随机生成的. ...

  4. Python免杀过360

    本文章仅供参考学习 作者:mantou 博客地址:https://www.cnblogs.com/mantou0/ 分离免杀 这个我就不多说了,效果确实不错,网上关于分离免杀的也有很多文章 不分离过3 ...

  5. Android applink 踩坑指南

    Android applink 踩坑指南 原理 接入步骤 将链接与activity关联起来 加入meta data 生成身份验证JSON 真机测试 结论 官方文档 原理 与url scheme不同的地 ...

  6. ArcGIS工具 - 批量删除空图层

    为了减少数据的冗余,我们经常需将数据库中的空图层(没有任何记录的要素类或表)删除,删除数据本来是一个很简单的操作,但如果数据量大,则需通过程序来处理.例如,删除成百上千个标准分幅DLG数据库中等高线数 ...

  7. Java的深拷贝和浅拷贝的区别

    一.拷贝的引入 (1).引用拷贝 创建一个指向对象的引用变量的拷贝. Teacher teacher = new Teacher("Taylor",26); Teacher oth ...

  8. 【Java刷题】初始化List应该选择ArrayList还是LinkedList

    文章目录 前言 题目 解题思路 遇到的坑:ArrayList和LinkedList 未通过代码 通过代码 小结 ArrayList和LinkedList的区别 在刷题的时候应该如何选择 排序效率 测试 ...

  9. python3进行3des的加密解密

    #秘钥长度正常24位,16位补齐第一个八位 import pyDes import base64 print('=======key1=======') keys='1234567890123456' ...

  10. Redis之key的淘汰策略

    淘汰策略概述 redis作为缓存使用时,在添加新数据的同时自动清理旧的数据.这种行为在开发者社区众所周知,也是流行的memcached系统的默认行为. redis中使用的LRU淘汰算法是一种近似LRU ...