如何画好一张架构图?(2)

简介: 如何画好一张架构图?

2、系统建模


通过业务建模完成了从现实世界到业务模型的构建,在此基础上,如何通过抽象完成业务模型到设计模型的映射,这是系统建模要解决的问题。从研发实现的角度,这个阶段会产出各种各样的模型图,比如实体模型图、时序图、状态图、各个层次的架构图等等,但是无论何种角度,何种层次,系统建模一定是在业务建模的基础上,完成业务需求到系统模型之间的映射;这其中涉及业务功能到系统能力、业务流程到数据流程的映射;系统建模更强调职责、依赖、约束关系,用于指导研发的落地实现。

抛开具体的时序图、状态图不谈,简单看几个维度的架构图(示意):


图片源于网络,为示意图,侵删上述几张图的视角、层次和面向用户各不相同,基本上都能看到整体,但是细节程度不同,侧重表达的信息也完全不同。那么系统建模时应该如何去做呢,这个过程中我常常用的方法是(不尽然如此):


  • “剥洋葱式”的由大到小,由粗到细,覆盖所有已知和未来可能业务场景;善于利用各种模型表述:自然语言、关系模型、时序图、状态图、流程图、各种层次架构图等等进行模型表述,充分表达各种业务场景并不断验证。
  • 核心实体抽取:抓住核心概念,核心关系完成核心模型建立。
  • 终极武器:所有的设计/逻辑模糊的点,将所有已知场景分别套入,自己讲给自己。


1)“剥洋葱”


在业务建模结果的基础上进行“剥洋葱”。这是一个不断拆解的过程,这个过程中的拆解非常重要的方式是就系统分工。如何分工?哪个模块负责什么?模块的输入和输出是什么?内部提供什么样的服务和能力?这几个问题在后文关于抽象的部分回答。一句话总结“剥洋葱”就是:从业务建模的“大局观”去按职责分工拆解成多个子系统、多个子模块,然后在模块层面进行细分,层层剥解。


2)核心实体抽取


关于核心实体的抽取,这里的关键问题是:哪些是实体?如何判断核心实体?如何抽取?抽取后的结果是什么样的?很难用一种方法论的形式去描述,我也没有完全形成我自己一成不变的方法论,但是我觉得如下三种方式可以供大家参考。

  • 对象的分析方法

实体(Entity):客观存在并可相互区别的事物称之为实体。实体可以是具体的人、事、物,也可以是抽象的概念或联系。

从这个概念理解,和我们面向对象万物兼对象的理解是基本一致的。所以实体的抽取也可以借鉴对象分析的方法:独立、可抽象、有层次性、在单个层次上又具备原子性。如下图是《Thinking in UML》中关于对象的分析方法。

  • 用例分析的方法

通过从业务用例中提取其中的关键词,不同的关键词可能表达了实体、关系、属性等等内容,从而完成模型分析与建立。这里引用六铢老师在《问题空间领域模型基本抽象方法》中的的内容,简述如下:

一句完整的用例描述中,首先找名词,以「主语」和「宾语」为主,这些名词基本可以确定我们的实体;其次找形容词,存在于「定语」和「状语」中,找到形容词基本可以确定对应属性的值;然后通过对用例的补充,细化,对名词进行定义,慢慢的,我们会得到我们的领域模型和对应的属性。最后通过动词&形容词(存在于【谓语】【状语】【定语】)来确定他们之间的关联关系。

  • 问题分析的方法

这是《聊聊架构》中提的方式,具体讲就是通过寻找问题的主体,然后分析主体的生命周期,进而通过区分生命周期里的关键活动来聚焦主体的关键属性和关键关系。推荐大家阅读前 9 章的内容,总计才 40 页的内容,可能会有所体会。这里举一个书中的例子:

一个笑话:一位女士对老公说:把袋子里的土豆削一半下锅。结果,所有土豆都下锅了,而且每个土豆被削了一半。

作者指出,这里其实是没有清晰的识别主体,这个主体不单是土豆,而是隐含的人要吃土豆,包括人和土豆两个实体,这两个实体之间的关系就是要解决的业务场景:怎样吃?如何吃?为什么吃?所以主体识别不清楚,可能会导致整体实现的偏离。当然实际过程中不会犯这么愚蠢的错误,但是也侧面说明核心实体的抽取是非常关键的。


3)终极武器:自己讲给自己


实际的业务开发中,往往一种业务设计实现要满足上层N个业务场景,这其中有共性也有个性化诉求,这个过程中我们很容易被多场景之间的异同搞混乱,要么逻辑不清晰,要么过度设计,要么考虑不周。

我观察过很多同学包括我自己,在一定的业务复杂度时容易失去设计的焦点。我的做法与业务建模类似,一定要逻辑对照:在所有的设计/逻辑模糊的点,将所有已知场景分别套入,自己讲给自己。请注意这里是“分别套入”,在当前的设计层次下一个场景验证完再去验证下一个场景,找出阻塞的、模糊的点,重新梳理再优化设计。系统建模的结果指导我们软件设计实现,所以一定要反复梳理打通,这个反复的过程其实也是提升架构能力的过程,累积到一定程度就会自然通透。

回到开始的那个问题:

模是什么?通过上面业务建模和系统建模的描述,简单来讲模就是业务的映射,这个映射的结果是业务模型、概念模型或设计模型,但是所有的出发点都是业务需求:客户是谁?核心诉求是什么?

如何建?上面通过业务建模和系统建模两个维度,从个人实践角度大概讲了常规的套路,建模的本质其实一个抽象的过程,但是上述业务和系统建模抽象的过程其实还有两个问题并没有完全说清楚:

  • 业务建模中“把书读薄”归类汇总,建立「大局观」,形成大图,这里按什么维度去归类?如何判断归类是正确的?
  • 系统建模中“剥洋葱”怎么拆?按什么拆?上述架构图中的层次、领域如何划分层次?边界在哪里?


说回抽象


Haskell 语言的设计者之一 Paul Hudak 曾说过一句略带夸张的话:编程中最重要的三件事是:抽象,抽象,抽象。

'abstraction, abstraction, abstraction' are the three most important things in programming.

如果要问程序员最重要的能力有哪些,我相信抽象一定是其中最重要的之一。那到底什么是抽象?

百度百科定义:

从具体事物抽出、概括出它们共同的方面、本质属性与关系等,而将个别的、非本质的方面、属性与关系舍弃,这种思维过程,称为抽象。

如果更精炼的概括:抽象就是做减法和做除法。通过舍弃非本质和无关紧要的部分,着眼于问题的本质,去粗取精;通过透过现象看本质,发现不同事物之间的共同之处,异中求同,同类归并,也就是做除法。上文中建模过程是共性抽象,通过不断的抽象达到某个状态为止,我理解这个状态没有确定性的答案,核心就是满足业务场景的需要,其实这背后也有一个边界的问题。

 抽象的角度

生活中处处都是抽象,但是我们似乎少了为什么是这样或那样抽象的思考。抽象是有角度之分的。

生活中我们常常说“我的观点是…”,其实这里的“观点”就是一个角度问题,从一定的立场或角度出发,对事物或问题所持的看法。以生活中的常见的实物来说(如下图),我们是否能快速的说出其中的相同点和不同点。

如图中已经标注的,我们从功用的角度对它们定义了椅子、桌子、凳子和柜子这样的区分,但显然很有很多很多角度,比如:物料、文字、高矮等等维度,从不同维度看过去,会有完全不同的相同点和不同点表述,所以,本质是什么?本质是:

  • 抽象角度其实也是分类的角度,角度不同,会导致完全不同建模方向和结果。
  • 抽象的角度就是建模的方向和目的(“屁股决定脑袋”)。

重新回到我们前边的两个问题,业务建模中我们谈到了归类,按什么去归类,答案呼之欲出,按我们的业务流程去归类、按客户的角色去归类,又回到了那个最初始的问题:客户是谁?核心诉求是什么?

同时,上文中我们提到,模是业务的映射,基于对抽象的理解,我们可以进一步展开:模是在确定抽象角度下的业务映射。

 抽象的层次

Wikipedia 关于抽象的定义中有一个关于报纸的例子:

1. 我的 5 月 18 日的《旧金山纪事报》

2. 5 月 18 日的《旧金山纪事报》

3. 《旧金山纪事报》

4. 一份报纸

5. 一个出版品

这五句话中,我们可以感受到抽象的层次,抽象层次越高,细节越少,普适性越强。再比如下图中关于网络模型的抽象,关于操作系统内核的抽象,我们可以明显看到,不同层次的抽象就是过滤不同的信息,最终留下来的信息才是当前抽象层次所需要的信息。从系统设计实现上来说,抽象层次越高,越接近设计,越远离实现,同时抽象的模型越不受细节的羁绊,稳定性越高,普适性越强,可重用性就越高。


那么这里抽象的划分层次的依据是什么?原则又是什么?我的经验是,划分抽象层次的依据主要包含两个:


  • 以抽象角度分层(可能一层是多角度的聚合)
  • 面对变化分层(用层次隔离变化)


其实这个也不能完全解释如何分层,原则是什么?我觉得这是几个最通用的原则:


  • 公用的往下走
  • 个性的往上走
  • 下层可以独立于上层存在
  • 控制下层的变化

考虑抽象层次的好处是不论在哪一个层次上,我们只需要面对有限的复杂度,从而专心考虑这个层次上的抽象是什么,要表达的信息是什么。



抽象的边界

除了角度、层次之外,我们还需要考虑抽象的边界。如果说层次考虑的是纵向维度的表达,那么边界考虑的是横向维度的表达。如何确定边界,一个总的原则是按照职责进行划分,这里的职责其实也就是分工。一旦职责确定,我们在做建模分析时就不需要把整个业务大局放进来从头到尾去分析一遍,我们只需要考虑当前分工下的上游和下游即可,这样的信息量大大减少,自然我们面对的领域复杂度也会降低到一定程度。

如果一定要给出边界的定义,我的理解是:边界是在确定抽象角度下,通过寻找核心的业务活动,抽取核心实体,进一步确定实体核心生命周期的结果。可能有一点点绕,关键词是:核心业务活动、核心实体、核心实体生命周期。

以现场娱乐行业为例,如下这张图包含了最高抽象层次下业务的全生命周期,这个抽象层次下的主体是什么,我的理解是票,项目生产的结果是票,分销或电商服务是对票的销售,现场是对票的核验,至此以票为核心实体的生命周期结束。

如果我们往下 Down 一层,从项目生产这一个业务活动去看,整个业务流程是这样:



项目管理->场馆座位分销->票房预测->场次管理->配额管理->绘座->票房规划


从生产这个视角去看,核心的实体不是票,而是场次(确定时间、确定地点、确定内容的一场演出或赛事),所有的关键业务活动都是以场次为维度,生产领域里需要考虑的主要就是场次的核心生命周期。

所以,在不同的抽象角度、不同的抽象层次,根据分工的不同会有不同的核心业务活动、不同的核心实体,边界的确定关键在寻找核心的生命周期。寻找生命周期的过程,就是发现内聚的过程;将所有关于生命周期的业务活动累积,就可以提升领域或模块的内聚性。

 抽象的评估

前边我们基本说清楚了抽象的角度、层次和边界,从三个维度确定了抽象的结果。那么如何评估抽象结果的好坏呢?答案是“高内聚,低耦合”,当然还有更多的原则,但是单从实践的角度,我觉得这是最最重要的。

耦合是软件结构中各模块之间相互连接的一种度量

内聚是一个模块内部各成分之间相关联程度的度量

“高内聚,低耦合”从内部、外部两个视角去评估抽象结果的好坏。这其中也有对应的原则和方法论,常规的套路是:

  • 每次从一个角度来切分,然后换多个角度来审视
  • 通过组合、拆分来精化、优化模型与设计(抽象的结果)
  • 关键的审视点:
  • 耦合性:减少模块间通信量
  • 内聚性:功能单一化
  • 变化的隔离性:减少信息依赖,建隔离层、虚拟层



抽象的方法论(套路)

我想,至此,我们说清楚了前面的那两个问题:

  • 业务建模中“把书读薄”归类汇总,建立“大局观”,形成大图,这里按什么维度去归类?如何判断归类是正确的?
  • 系统建模中“剥洋葱”怎么拆?按什么拆?上述架构图中的层次、领域如何划分层次?边界在哪里?


总结前面说的所有关于抽象的内容,形成抽象的方法论:


  • 抽象有两种方法,一种是自顶向下,另一种是自底向上
  • 业务建模,是从小到大,从局部到整体,自底向上的归纳、演绎的抽象过程
  • 系统建模,是从大到小,从整体到局部,自顶向下的拆解、切分的抽象过程
  • 但不绝对,自上而下和自下而上,往往在过程中是随意切换的

下面这张图来自于《Thinking in UML》,我觉得这个循环的过程可以表达上面这四个点,供大家参考。

如何画好一张架构图?



相关文章
|
6月前
|
程序员 数据库 开发者
值得收藏!如何快速画出一幅漂亮的架构图
这篇文章总结了常用的架构图类型,可以借鉴笔者提供的模板,快速地产出符合业务需要的架构图。
161545 95
|
运维 前端开发 架构师
一文搞定如何画出更加优秀的架构图
一文搞定如何画出更加优秀的架构图
1026 0
一文搞定如何画出更加优秀的架构图
|
3月前
|
开发者
如何画好一张架构图/业务图/流程图,掌握这4个关键点
作为一个开发,日常工作中免不了要画一些图,无论是技术架构图还是业务流程图。基于个人的一些经验,作者分享了他的作图方法,给大家一点思路提供参考,希望在未来的工作、生活中都能有所帮助。
1430 2
|
9月前
如何画好业务架构图。
如何画好业务架构图。
173 0
|
8月前
|
程序员 数据库
如何快速画出一副漂亮的架构图
为什么要画好一幅架构图?一幅漂亮的架构图既是创作者的深度结构化思考和表达,对于读者来说也更加容易理解架构所要表达的意思。
30176 16
|
9月前
教你画出业务架构图
教你画出业务架构图
572 0
|
存储 运维 架构师
怎么画出好的架构图,架构师必备。。
怎么画出好的架构图,架构师必备。。
895 0
怎么画出好的架构图,架构师必备。。
|
12月前
|
运维 架构师 安全
如何画好一张架构图?(3)
如何画好一张架构图?
23906 5
如何画好一张架构图?(3)
|
12月前
|
测试技术 定位技术 uml
如何画好一张架构图?(1)
如何画好一张架构图?
753 0
|
存储 消息中间件 JavaScript
老司机教你,如何画出优秀的技术架构图?(硬核知识)
老司机教你,如何画出优秀的技术架构图?(硬核知识)