前言
如果你的团队中有新人入职,你将如何向他完整地介绍团队所负责的系统,以让他更快上手呢?
面试时,面试官问"请详细讲一下你负责的系统",你将怎么讲呢?
答案自然有很多,而本文将介绍的 Kruchten's 4+1 View Model 是其中一个经典的解决方案。它的思路是分别从多个孤立的视角来描述这个系统。(论文原文标题:Architectural Blueprints---The "4+1" View Model of Software Architecture, 感兴趣可自行搜索)
Kruchten's 4+1 View Model 诞生于1995年,是面对当时的传统软件行业提出的理论,作为一个经典理论,它直到现在也有很强的指导意义。当然,在现在的大规模分布式集群、微服务、云原生等新趋势下,也需要有所改进。
PS:笔者在搜集相关资料时发现,也不知是以讹传讹还是哪个版本的新理解,好多中文文章里所描述的4+1 view 虽然每个视图的名字和原版一模一样,但含义已经变了。比如Process View在这些文章里变成了时序图和数据IO。如果有人知道前因后果,请指正。
经典的4+1模型

原版的4+1模型如图所示,由四个视图+Scenario(情景)组成。
逻辑视图(Logical View):
由上图可知,逻辑视图是所有5个视图里最重要的,是其它视图的来源。这很好理解,无论系统多复杂多精妙,最终都是要服务于需求。有业务需求才有具体的业务逻辑,有了业务逻辑才有了逻辑模块划分,也就才有了逻辑视图。
在逻辑视图里,我们暂时不需要关心代码实现、集群、并发等问题,只关心系统内部的业务逻辑和能提供的功能。也就是说,把系统里的各部分理解成一个个"组合起来的能实现特定功能的子模块", 并描述各功能模块之间的关系(继承、组合等)
举个例子,在这一层里,我们不需要关心API网关是怎么实现各种流量治理的, 也不需要关心它的集群是如何扩缩容的,在哪个云商的哪个区域部署的,只需要把它抽象成一个"API网关"子系统,而它下面又有"限流器" "鉴权组件" "路由组件" 等。
从面向对象的视角来看,逻辑视图有点类似于UML里的ER diagram

处理视图 (Process View)
这里把 Process 译为"处理"可能有些晦涩了,个人认为翻译成"执行"可能更准确一点。而本视图也是原版4+1view里最难理解的一个。那么它具体是什么 呢?
一言以敝之,Process View 表示在考虑了并发、容错、性能等"非功能需求"后,业务逻辑要如何实现。
换句话说,本视图表示的是如何**"处理"逻辑视图**,也就是说,如何"执行"逻辑视图里所描述的业务逻辑。
而这个视图所使用的图也比较灵活多变,也不仅限于图,表格、文档、伪代码... 都可以。
举个例子:逻辑视图里有一个"用户模块",用来提供各种用户信息。到了处理视图里,就需要描述这个用户模块如何加载和同步用户数据,比如"使用一个100ms的定时器,定时查数据库检查数据更新"的描述,这里面的"100ms定时器"和"查数据库"就是"非功能需求"了。
开发视图 (Development View)
简单来说,就是从程序员的视角来看这个系统。这个视图又有两层含义。
一是代码层面。比如工程代码里有哪些类、结构体、函数,主程序入口在哪,代码分了哪几层,每层有哪些功能,每个功能里调用哪些函数,项目代码的路径结构是怎么划分的,某个类库是用的哪个设计模式...
二是子系统层面。与上面的逻辑视图的区别在于,逻辑视图里分出来的各种子模块是完全从业务逻辑、功能需求上来看的,不考虑具体实现。而这里的是具体代码实现中的子模块、子系统划分。 例如一个信息流App里最基本的"按用户兴趣推荐文章"的功能,从逻辑视角来看,是"文章推荐"子模块;而在开发视图,则是"后端业务模块" - "推荐算法模块" - "大数据模块" 等多个模块(如果是微服务,甚至由10多个微服务)联合起来工作才完全了这个功能。
一般来说,我们最常画的、最熟悉的也是开发视图。因为它也是最符合我们的思维视角。
物理视图 (Physical View)
也就是软件在物理层面上的拓扑结构。
整个系统在物理层面上的服务器是如何部署的,每个物理机如何组成集群,每个集群内部的通信,集群之间的通信、各物理机的机型等。
在本论文提出的年代,IT系统还是以传统软件行业为主,甚至多数都是单点服务。因此在原文的表述里,物理视图主要指系统内部各节点之间的网络拓扑和进程间的调用都包含在里。
但如果是现如今的互联网主流系统,各种分布式、微服务、云原生概念。情况就有了变化。除了依旧需要表示出各物理节点之间、进程之间的关系外,还需要与时俱进,增加至少如下信息:
- pod内container之间的调用关系(如果是K8S)
- 使用的Saas, Paas等服务
- 流量的路由方式
- 集群的所在区域、可用区等
情景(Scenarios)
不需要多说。
在1995年的当年可能还是个比较新鲜的事物,现在应该非常好理解了,在敏捷开发里这个概念非常普遍。
也就是说,通过几个典型的用例,表现出整个系统是如何被用户所使用的,从而把这多个视图串联起来。
具体如何描述Scenarios, 请参考各种敏捷开发相关的文章。
由于本方法的思路是从不同的孤立视角来展示架构,各视图之间割裂,难以形成一个立体视角。就像一个球体过球心有无数个平面一样,每个系统都是立体的,也无法仅从几个平面就完全描述。
而我们如何从这几个孤立视角建立起对整个**系统架构的"立体感"**呢?用例,也就是场景视图,就是建立立体感的关键。
在实践中,一个新入职的员工往往会被分派一些小需求,用来帮助他熟悉项目。这些小需求也是"用例"的具现化。因此,平时多积累大量的高质量情景用例,是个好习惯。