对于众多开发者而言,架构图不仅是一项不可或缺的技能,更是他们理解、规划和构建软件系统的关键工具。然而,面对多样化的系统需求和复杂的业务逻辑,如何画好一张架构图,成为了许多程序员面临的共同挑战。今天,我们特邀了同程旅行资深架构师、腾讯云 TVP 李智慧老师,李老师也是畅销书《高并发架构实战:从需求分析到系统设计》的作者 ,他将以深厚的技术功底和丰富的实战经验,为我们揭开常见架构图的神秘面纱,解析它们在软件设计不同阶段的选用原则与应用场景。
//////////
《如意、悟净、悟能——操作系统界的“黑神话”特性》「鹅厂程序员面对面」本周三晚直播精彩继续,预约观看有机会抢鹅厂周边好礼!
在软件开发领域,成为一名架构师是很多程序员的“终极梦想”。架构师所需具备的技术能力是多维度且全面的。但成为架构师,首要的能力一定是绘制架构图,因为系统需要设计,设计就需要架构图,而架构师就是那个画架构图的人。俗话说“一图胜千言”,架构图作为架构师和产品经理、开发工程师、测试工程师等各种角色之间进行沟通的语言和桥梁,其重要性不言而喻。
我们先看一张关于架构的架构图,架构图是描述系统主要组成部分及其关系的图。那么架构自身由哪些部分组成?与其相关联的部分有哪些?这些部分之间的关系是什么?
如上图所示,每个系统都有一个架构,架构由架构元素和元素间关系组成,这些元素和关系又会通过架构文档来展示。架构文档需要满足不同相关方的关注点,比如开发工程师关注代码如何实现;运维工程师关注系统需要多少硬件、网络布局如何;业务方关注实现的功能有哪些;架构文档为了满足不同的关注点,需要通过不同的架构视图来呈现。这些架构视图就是我们常说的架构图,所以,实际工作中,架构师不是要画好一张架构图,而是要根据不同需求,画好很多张架构图。
画架构图的方法有很多,目前最主流的方法依然是 UML,即统一建模语言。UML 包含的图形总共有10种,其中常用的有7种:类图、序列图、组件图、部署图、用例图、状态图和活动图。
类图是最常见的 UML 图形,用来描述类的特性和类之间的静态关系。
一个类包含三个部分:类的名字、类的属性列表和类的方法列表。类之间有6种静态关系:关联、依赖、组合、聚合、继承、泛化。把相关的一组类及其关系用一张图画出来,就是类图,类图示例如下图:
类图之外,另一种常用的图是时序图,类图描述类之间的静态关系,时序图则用来描述参与者之间的动态调用关系。
从图中可以看出,每个参与者有一条垂直向下的生命线,这条线用虚线表示。而参与者之间的消息从上到下表示其调用的前后顺序关系,这正是“时序图”这个词的由来。每个生命线都有若干个激活条,也就是那些细长的矩形条,只要这个条出现,就表示参与者是激活状态的。
时序图通常用于表示参与者之间的交互,这个参与者可以是类对象,也可以是更大粒度的参与者,比如组件、服务器、子系统等。总之,只要是描述不同参与者之间交互的,都可以使用时序图。
组件是比类粒度更大的设计元素,一个组件中通常包含很多个类。组件图通常用来描述物理上的组件,比如一个 JAR、一个 DLL 等等。在实践中,我们进行模块设计的时候,用得更多的就是组件图。
组件图描述组件之间的静态关系,主要是依赖关系,如果你想要描述组件之间的动态调用关系,可以使用组件时序图,以组件作为参与者,描述组件之间的消息调用关系。
部署图描述软件系统的最终部署情况,比如需要部署多少服务器,关键组件都部署在哪些服务器上。
部署图是软件系统最终物理呈现的蓝图,根据部署图,所有相关者,诸如客户、老板、工程师都能清晰地了解到最终运行的系统在物理上是什么样子,和现有的系统服务器的关系,和第三方服务器的关系。根据部署图,还可以估算服务器和第三方软件的采购成本。
因此部署图是整个软件设计模型中,比较宏观的一种图,是在设计早期就需要画的一种模型图。根据部署图,各方可以讨论是否对这个方案认可。只有对部署图达成共识,才能继续后面的细节设计。
用例图反映用户和软件系统的交互,描述系统的功能需求。
图中小人形象的元素,被称为角色,角色可以是人,也可以是其他的系统。系统的功能可能会很复杂,所以一张用例图可能只包含其中一小部分功能,这些功能被一个矩形框框起来,这个矩形框被称为用例的边界。框里的椭圆表示一个一个的功能,功能之间可以调用依赖,也可以进行功能扩展。
状态图用来展示单个对象生命周期的状态变迁。
业务系统中,很多重要的领域对象都有比较复杂的状态变迁,比如账号,有创建状态、激活状态、冻结状态、欠费状态等等各种状态。此外,用户、订单、商品、红包这些常见的领域模型都有多种状态。
这些状态的变迁描述可以在用例图中用文字描述,随着角色的各种操作而改变,但是用这种方式描述,状态散乱在各处,不要说开发的时候容易搞错,就是产品经理自己在设计的时候,也容易搞错对象的状态变迁。而 UML 的状态图可以很好地解决这一问题,一张状态图描述一个对象生命周期的各种状态,及其变迁的关系。
如图所示,在一个网约车系统中,订单状态有创单、派单中、已派单、行程中、已取消、待支付、已完成几种,而每种状态之间变迁的原因可以在图中清楚呈现,状态与变迁关系用一张状态图就可以搞定。
活动图主要用来描述过程逻辑和业务流程。UML 中没有流程图,很多时候,人们用活动图代替流程图。
活动图和早期流程图的图形元素也很接近,实心圆代表流程开始,空心圆代表流程结束,圆角矩形表示活动,菱形表示分支判断。
此外,活动图引入了一个重要的概念——泳道。泳道表示一个领域范围,有时候也被称为子域,如上图中三个领域范围:酒店、区块链、车辆运营公司。活动图可以根据活动的范围,将活动根据领域、系统和角色等划分到不同的泳道中,使流程边界更加清晰。
在软件开发的过程中,架构图不仅是沟通的工具,更是指导设计与实施的关键蓝图。它们帮助开发团队在需求分析、概要设计、详细设计等各个阶段中,清晰地定义系统结构、功能划分及交互关系。对于这七种常见架构图在软件设计不同阶段的选用原则与应用场景,我根据自己的设计实践,有如下建议:
最后,我想说的是,UML 是一种 language,语言的主要用途有两个:一个是思考,一个是交流。所以,当你在思考软件架构的时候,不妨动手把你的思考画下来;当你想要告诉别人你的架构设计的时候,也不妨画一些架构图给对方。
也正如交流的目的是为了沟通思想,而不是炫耀语法;画架构图的目的也是为了让他人(包括自己)了解架构的设计,而不是画得漂亮。所以画架构图的时候,不必纠结自己画得是不是标准、图形元素是不是使用正确,而是要考虑你的架构图是否准确表达了你的架构设计意图,别人是否能正确理解。
可能你已经发现,我在上面的UML图示例中,就使用了一些不规范的UML模型元素,就像说话一样,即使你发音是有些口音、包含一些方言,但是只要对方能听懂,就没有问题,反而是如果怕发音不标准而不敢说话,才可能会错过整个世界。
这里,我推荐一个简单的在线画图工具:https://app.diagrams.net/ 画下你的第一张架构图,开始你的架构师之旅吧。如果你想参考一些具体的案例,想看看一张架构图是如何具体表达某个设计思路的,而多张架构图又是如何构成一个架构设计文档的,推荐你阅读我写的《高并发架构实战:从需求分析到系统设计》。
作者简介
李智慧,同程旅行交通资深架构师,腾讯云 TVP,长期从事大数据、大型网站架构的研发工作,曾担任阿里巴巴技术专家、Intel 亚太研发中心架构师、宅米和 WiFi 万能钥匙 CTO。Apache Spark 源代码贡献者,著有畅销书《高并发架构实战:从需求分析到系统设计》、《大型网站技术架构:核心原理与案例分析》,极客时间《从零开始学大数据》专栏作者。
-End-
原创作者|李智慧