这是一篇来自高级技术专家箫逸畅谈架构经验的经典好文。在本文中你将了解到:架构图是什么?为什么要画架构图?如何画?有哪些方法?
什么是架构图?
如何画好一张架构图,要做好这件事情首先要回答的就是什么是架构图。我们日常工作中经常能看到各种各样的架构图,而且经常会发现大家对架构图的理解各有侧重。深入追究到这个问题,可能一下子还很难有一个具象的定义,如果我们把这个问题进行拆分(如下图)理解起来就会容易一点。
架构图 = 架构 + 图
按照这个等式,我们可以把问题转换:
- 架构是什么?
- 图是什么?
图是什么?这个比较容易回答,图是一种信息的表达方式,所以架构图,即表达“架构”的图,也就是一种架构的表达方式。也即:
架构图 = 架构的表达 = 表达架构的图
按照这种思路我们需要回答:
- 什么是架构?要表达的到底是什么?
- 如何画好一张架构图?
接下来的内容基本上就是按照这两个维度来做分析。
什么是架构?要表达的到底是什么?
Linus 03 年在聊到拆分和集成时有一个很好的描述:
I claim that you want to start communicating between independent modules no sooner than you absolutely HAVE to, and that you should avoid splitting things up until you really need to, because that communication complexity often swamps the complexity of the actual pieces involved in it.
让我们认识到一种现象,把复杂系统拆分成模块,似乎并没有降低整个系统的复杂度。它降低的只是子系统的复杂度。而整个系统的复杂度,反而会由于拆分后的模块之间,不得不进行交互,变得更加复杂。
我理解这里描述的系统拆分就是架构的过程,基本出发点是为了效率,通过架构的合理拆分(无论是空间还是时间上的拆分),最终目的让效率最大化。那到底什么是架构,其实没有完全统一且明确的定义,如下三个定义可以参考。
在百度百科上的定义:
架构,又名软件架构,是有关软件整体结构与组件的抽象描述,⽤于指导⼤型软件系统各个方面的设计。
在 Wikipedia 上的定义:
Architecture is both the process and the product of planning, designing, and constructing buildings or any other structures.
ISO/IEC 42010:20072 中对架构有如下定义:
The fundamental organization of a system, embodied in its components, their relationships to each other and the environment, and the principles governing its design and evolution.
这三个定义也是见仁见智,但是我们基本可以得出:架构体现的是整体结构和组件之间的关系。
架构的本质
这里引用三个观点来探讨架构的本质:
- 架构的本质是为了管理复杂性。
- 架构的本质就是对系统进行有序化重构,不断减少系统的“熵”,使系统不断进化。
- 架构的本质就是对系统进行有序化重构,以符合当前业务的发展,并可以快速扩展。
上述三个观点提到的内容,基本表达了架构的核心目的:管理复杂性,效率最大化。以及架构的两个主要变化来源:一个是以改善软件质量为目的的内在结构性变化;另外一个是以满足客户需求为目的的外在功能性变化。无论是何种变化,在我看来架构都是在不断的判断和取舍,在业务需求和系统实现之间做权衡,从而应对未来变化的不确定性,下图可以比较粗浅直观的表达这种理解。
要表达的是什么?
在 EA 架构领域,有两种常见架构方法 RUP 和 TOGAF,这两个框架也是我们常常了解架构分类的两个维度。从个人的角度,我自己觉得 TOGAF 9 的分类方式更加广泛使用(如下右图)。
结合日常的业务开发,其实我们更多的是关注业务架构和应用架构,所以把上边的表达式进一步的拆解,在回答如何画好一张架构图之前,我们需要关注业务架构和系统架构,讨论清楚如何进行业务架构和系统架构。
架构的过程其实就是建模的过程
我们都知道现实世界到软件世界或者面向对象的世界的过程,是一个不断抽象的过程,这其中的方法就是不断的建立模型。从现实世界到业务模型,从业务模型到概念模型,从概念模型到设计模型,通过不断地抽象去粗取精,形成对现实世界的层层抽象,所以架构的过程其实就是建模的过程。至此,我们有必要了解一下什么是建模。
百度百科定义:
建模就是建立模型,就是为了理解事物而对事物做出的一种抽象,是对事物的一种无歧义的书面描述。
《Thinking in UML》定义:
建模(Modeling),是指通过对客观事物建立一种抽象的方法用以表征事物并获得对事物本身的理解,同时把这种理解概念化,将这些逻辑概念组织起来,构成一种对所观察的对象的内部结构和工作原理的便于理解的表达。
从上述两个定义基本可以了解到建模就是抽象,对业务或现实世界的抽象,虽然不足以帮我们理解架构本身,但是可以将我们上述关注的业务架构和系统架构进一步向下 Down 一层,架构的过程是建模的过程,我们转换成两个简单的问题:模是什么?如何建?
模是什么?如何建?
这是两个比较容易陷入理论性的问题,我们跳出来从结果看过程。接下来通过已经产出的一些架构图来反向看这些架构图是如何产出的,同时来回答这两个问题。
1、业务建模
回到当下业务本身,对我而言也是全新的,在最初接触的时候凭仅有的行业背景去理解,结合了大量的文档阅读最终产出了如下图示的《业务核心流程图》和《业务功能模块图》。这两张图基本上就涵盖了所有的业务内容。左边的业务流程图得到了这个行业 20 多年从业经验专家认可,他认为这就是 20 多年所从事的业务内容(涉及到项目的保密性质,大图故意缩小了,但不影响整体信息传递)。
回溯整个过程,特别是左侧的业务核心流程图,我们看这张流程图很容易构架起一个基本逻辑,纵向是不同的业务角色和系统,横向是时间的推进。但最开始的理解和分析是极其耗时和压力极大的过程,这个过程中我所用的方法就是:
- 把书读厚:大量的信息输入,同时探求可能性。
- 把书读薄:归类汇总,形成大图。
- 逻辑对照:确保理解和分析的正确性。
1)把书读厚
下图基本涵盖“把书读厚”的过程,汇聚大量的文档信息,尝试用多维度去形成逻辑。这个维度可能是依据历史经验,也可能是依据文档内容,比如在形成业务大图的过程中,我曾按可能的场景逻辑、可能的系统或领域逻辑分别把多个文档中的内容归类,探求可能性。
这个过程会很枯燥,特别是涉及一些业务的术语内容,理解起来就会很困难。我的方式就是把自己当做一名“探索者”,如同我们玩游戏一样,常常问自己“我的游戏地图全部点亮了吗?” 未必要照顾到所有细节,但是需要力求覆盖整体内容。仔细想想,似乎也和日常的读书类似,这期间值得注意的是:
- 重点关注一些业务概念被界定的地方、一些与自己逻辑推理有出入的地方。
- 不断调整自己阅读过程中记录的维度,矫正自己的分析方向。
- 老老实实用文档中的原话来记录和呈现(这点很重要,特别是阅读英文材料,最好原汁原味的记录,有助于提升自己的专业性)。
2)把书读薄
这个时候的重点是建立“大局观”,尝试梳理自己的逻辑主线,常规逻辑上讲都会划分为横纵,或者矩阵式的框架,当然这需要建立在前期的理解和分析上,这里常常隐含一个最重要的假设:系统一定是给人用的,一定是解决客户问题的,否则毫无存在的意义。所以核心的套路是:谁?用什么样的服务/功能/能力?解决什么样的问题?从而刻画出:参与者角色、系统能力、交互关系,需要常常问自己的是:边界是什么?输入输出是什么?逐步通过用例来梳理出业务功能,形成角色—>主流程—>分支流程,进而通过不断地归纳演绎形成最终的业务抽象描述“一张图”。
一个小的细节是不能妄图通过这些过程迅速在大脑里完成大图的绘制,还是需要从小的环节做起,把一部分小的业务闭环做成一个个的小组块,不要让它再占用大脑的空间,然后逐步整体思考和把握,渐进式地形成大图。与此同时,大图的样式美观先完全忽略,走通逻辑再细致调整。之所以强调这个细节,是因为尝试通过“一张图”去描述一个非常大的业务本身就是件很有挑战的事情,如果不这么做容易让自己变得焦虑和急躁,这是一个慢功夫,需要耐心,需要在关键阻塞的地方慢下来,甚至一遍一遍的反复才能最终完成。
3)逻辑对照
这是一个闭环封装的过程,把前期“读厚”过程中的记录,一些逻辑细节、关键流程都要逐一放到大图里去对照验证,确保业务理解的完整性和准确性,确保业务抽象能够覆盖所有已知的业务用例,甚至能够支持可能的业务场景。这个环节也是必不可少的部分。
总结一下业务建模(如下图),通过上述三个主要的过程,我们基本可以产出一些业务架构的大图、框图、流程图、用例图等等,是什么样的图并不重要,重要的是这个图面对的是谁?主要用来做什么?我后边也会讲到画图角度的问题。从我们目前的业务场景上看,业务架构图的核心目的是统一共识、减少沟通成本,无论是项目中的哪个角色大家都能讲一样的话,描述一样的事情。建立对话能力和对话语境,特别是有大量外部客户的时候,一方面体现我们自己的专业性很重要,另外一方面这种与客户对话的能力更重要,这也是上文中提到为什么要尽可能用原汁原味的文字去呈现一张图的目的。