如何画架构图

前文讲到,写好文档,才能少挨骂。在此基础上,如果图表画得好,你可能还会被夸。

本文以架构图为例,讲一讲如何给软件文档画图。

明确受众

写文档要明确受众,画图也是一样,想好了给谁去画、为什么去画、目标读者关心什么内容,才好进一步去思考想要传达什么信息。即使都是给同事看,你也得区分一下,是给开发人员看,还是给运维人员看,还是给什么人去看。就算是为了去找用户装逼,你画得也得像那么回事对吧。

怎么判断图画得好还是画得不好呢?一方面就是直观,读者他能看得进去,不会被乱七八糟的样式劝退;另一方面是你画出了读者关心的内容,通过你的图能够解决他的某种困惑(例如让开发人员了解系统技术架构,让产品人员了解系统功能与功能之间的关联);还有一方面,他看完了之后,对这张图的理解也跟你是一样的,你要表达的信息有效地传达给他了。

图的目的是帮助认识与理解。认识新事物,由浅入深才能更好地掌握。画图的时候也是一样,你需要假设,图的读者要么没参与项目,或者参与程度不深,或者跟我们想法不一致,因此需要用图表让他们先在浅层有个直观的认识,搞清楚之后才能深入细节。一开始就讲细枝末节的东西,一般人肯定一头雾水。

想好你要表达什么内容

一张图是不够的

有时候,你就是无法只用一张图就把事情说明白。例如有人总想给系统画一个超级架构图,把系统的核心功能、应用组成、物理部署、系统间关系等信息用一张图全部表示出来,但他们画出来的东西既不好看,也没能达到预期目标。

系统要是只有几万的合同额,功能很少,只有一台应用服务器、一个数据库,只对接几个外部系统,倒是没什么问题。然而,服务器稍微多一点,集成关系稍微复杂点,摆放的时候就要头疼,画出来的线条也是纵横交错,不仅自己看着难受,外人理解起来也很费劲。

所以,画图之前要明确主题,一张图有且只有一个主题。例如,主题是服务器的物理部署,那么网络拓扑、应用组成、系统间关系等内容都可以简略地画,甚至不画。然后再换几个角度,从不同角度来表达,各有各的侧重点,从而把简化与忽略的内容都给补上。这样这些图就可以作为一个整体来达到完整、清晰表达的效果。

举个简单的、传统应用的例子。为了方便叙述,我们称其为“XYZ系统”:

这张图专注于XYZ系统的物理部署,一看就能知道有多少台服务器,每台服务器做什么用途的。那么这个系统是否与周围系统存在对接关系呢?我们用第二张图来表达:

虽然这张图不太匹配软件工程的理论,但是不要紧,能把意思说清楚就行。这张图专注于系统间关系的描述,于是将XXX系统简化为一个应用服务器与一个数据库服务器(当然,因为有物理部署图,所以我们知道XXX系统不只两台服务器)。从图中可以看出,XXX与B、C、D是通过接口进行对接的,而与A是通过ETL进行数据库数据传输的。

除了从不同角度描述,有时还需要从不同深度来描述,就像百度地图展示那样,先是缩小到整个中国,然后放大到省、市、区县、镇或街道,一层一层细化。数据流图就是这样表达的。

图内元素的性质要统一

架构图经常使用方框、箭头、icon之类的符号,这些都是图的元素。

画图时候要搞清楚,各类元素都是什么性质的?画了一个框,框里面的内容是哪种类别呢?是应用系统(application)?是功能模块(module)?服务器软件?系统组件(component)?类(class)?还是用户(user)?

连接两个框的箭头则是要表达关系,那么是什么关系呢?系统组件间的对接(动词或名词)?是流程(名词)?还是流程的流动(动词)?是数据(名词)?还是数据的流动(动词)?

如果连这个问题都没搞清楚,那么画出来的图在逻辑上都是混乱的,更别提准确了。

想清楚之后,例如我们确定框代表“应用系统”,线条代表“前后端接口调用的对接关系”,那么我们就可以开始进行梳理:我们要做的系统中,包含哪些应用系统?出一个清单,把这些系统都摆到图上,排个顺序,差不多之后再挨个考虑接口关系,有关系的画线,没关系的不管了。

对于稍微复杂的图,我们还要讲究一个层次感,要不然看起来就是一团糟,甚至实现起来也是一团糟。例如软件架构通常采用分层架构,分为展示层、业务层、持久层、数据层等等,并且这几层不光对组件进行了分割和隔离,还指出了一种递进关系,用户访问的是展示层,展示层调用业务层,业务层调用持久层,持久层调用数据层,结构清晰,层次分明。画图的时候,则是从外到内地画,先把大的层次摆出来,然后再找其中一个层次,想一想是继续分层,还是明确该层内部的框是什么性质(应用系统?功能模块?……),然后把框都摆上去。

举一个案例:

这是一个简单的整体架构图,将系统分为了四层,每个框中放的是组件,没有表达组件之间的关系。系统模块被包在了“业务应用”与“应用支撑”两个组件之内。

仍然是上面的图,我们换一种画法:

虽然框的含义是不统一的,但是在每个层次当中是统一的。最外层,用户使用了一个icon,而“业务管理系统”与两个“XX外部系统”都是“系统”。进入“业务管理系统”内部,里面的框均为“组件”。外层的线条表示了系统与系统的关系,而内层的线条绘制的是组件与组件的关系。那么,具体是什么关系呢?图中统一使用动词进行了表达,所以这些关系都是主动发起的动作。

再看一个简单的反面案例:

这图让人觉得不舒服,除了美观原因以外还有一点:在这张图里,框框一会儿表示一个应用系统(支付系统),一会儿又表示一台服务器(消息推送服务器),一会儿又表示一个组件(消息推送模块)。画线的时候,一会儿是应用系统对接应用系统(活动系统与服务平台、移动平台),一会儿又是应用系统对接组件(支付系统与报名支付模块),既有系统也有模块;一会儿是交互关系(推送),一会儿又变成了状态关系(用户数据),既有动词也有名词。全图连要表达什么意思都是不统一的,只因要素少所以还大概能表达出什么意思,要是再复杂些,看都看不懂,就更别谈准确了。

先不要讲究格式,把东西堆好再说

先构图,然后再考虑完善内容。

除此之外,在定稿之前,图可能还要反复修改。你可能会识别出很多疏漏之处,例如识别出新的系统,或者新的关系,然后还要重新考虑元素摆放,调整线条走向。所以不要一开始就画得很精致很完美,先做个差不多的草稿,把东西堆好,理清思路,感觉差不多之后再好好调整样式,否则改起来太费劲了。

不是所有东西都需要在图上表达

图的表达深度是有限的,所以不要用有限的空间来进行无限的解释,要不然还要软件文档做什么?

仍然以最上面的XYZ系统的两张图为例。

肯定有人会问,XYZ系统部署在哪个网络环境?XYZ与A、B、C、D的具体对接方式与数据项呢?是通过哪台服务器实现的?假如D信息推送只通过应用服务器2来实现,我们要如何表达呢?

  • 网络环境,比如都在阿里云部署,我们在图上再套个框,把服务器都包进去,稍微描述一下,阿里云。
  • ABCD四个系统对接,简单画一下,OK,对接细节画不出来,所以不画了,反正不是这张图的核心主题。
  • 顺便加一下用户访问的信息,一个PC端,一个基于HTML5的移动端,也不影响主题,稍微描述一下。

改完之后:

图的主题还是物理部署,其他(系统对接、用户访问)都是顺带的,画出来可以增加信息量,而且不影响表达主题,不画也不会带来损失。至于对接方式、数据项、精确的服务器,这样的细枝末节就别画了——你描述细节,那么应该描述到什么程度呢?Restful API?有B数据查询、查询回调、状态检测等服务接口?数据查询主要查询x、y、z等数据项?网络策略如何?要是真把这些信息都写上,不仅会把图弄乱,而且还跑题,干脆就全部忽略。

图只是起点,不是终点。图的目的就是简单直观,简单的、不影响表达主题的信息可以适当加一加,增加信息量,但是,复杂的、不直观的细节,可以使用更好的表达方式,没必要非得挤到图里面去描述。

处理图片与解释说明的关系

如果图的格式是你自己发明的,又红又绿,又有实线还有虚线,既有方块又有三角,那么你是不是应该该做个图例,让人知道你那堆符号是什么意思?

作出来的图还应该是自解释的:拿到你的架构图,读者很容易能看到系统划分了几个区域或几个层次,每个区域有什么实体,每个实体之间有什么关系,用不着请你专程跑来一对一为提供讲解服务。

当然有时候它真的不是那么直观,所以你可以再写一段文字,大概讲一下图的构成,分成几个块,每一块主要有什么东西,哪些是需要重点关注的流程之类的信息。注意按从整体到部分的顺序描述,按流程的顺序写,因为正常看图就是这样来看的。内容有点多的话,就用1234的序号或者小标题来分割一下,这样也便于找个角落把图上未能表达的一些细节补上。

图与解释文字应该保持一致,文档与实际的实现也应该保持一致。当然,现在已经是内卷的时代,大家能把活赶出来就已经很不容易,很难再挤出时间来维护文档,但还是希望大家至少能维护一个备忘录,平时也多加注意,让后来的人能够知道文档的哪些地方已经过时。

有标准规范的图,不要自己发明格式

有些图表的目的与格式都是比较固定的,绘制时需要遵循一定的规范,包括但不限于:

图表 目的
流程图 系统运行流程
数据流图 描述系统输入、输出与数据处理
实体-关系图(E-R图) 描述实体类型、属性和联系
用例图 描述“用户需要什么”
活动图 描述一个过程中的活动发生顺序
顺序图(时序图)、通信图 描述一段时间内的一连串交互
类图 描述面向对象分析中各类之间的关系
状态图 分析一个对象的不同状态及状态转移

请使用业界常用的格式来绘制这些图,不要自己胡乱发明符号。

如果你不确定你要画的图有没有标准规范,那么请先到网上搜一搜,搜不到的话再自由发挥。

本系列文章