1.1 简单的架构知识模型

在程序员成长为架构师的过程中,面临的第一个阶段是知识体系构建,需要学习众多且分散的架构知识点,涉及面向对象、DDD、TOGAF、敏捷、DevOps、中间件、微服务,以及高并发、高可用、可扩展等。

这些知识点之间似乎缺乏一条清晰的学习主线或关联关系。不过,有一点是非常明确的:所有架构知识都是为了软件系统开发服务的。因此,我们尝试从这个视角去推导架构知识的模型。

首先,软件是一个系统。按照系统的定义,所有系统都是由元素、关系以及功能/目标3个要素组成的。其中,元素代表“是什么”,功能或目标代表“干什么”,而关系则代表“怎么干”。

在软件系统研发过程中,我们通常先从客户侧获取需求,即目标系统的功能或目标,再通过架构设计反推出系统的组成元素以及元素之间的关系。

因此,简而言之,架构设计是由软件系统的“干什么”来推理出“是什么”和“怎么干”的过程,是一个由果到因的过程。架构设计的过程简化如图1-1所示。其中,“干什么”通过需求来获取,而“是什么”和“怎么干”则属于架构编排工作,至此可以初步得到一个架构知识模型。

图1-1 架构设计的过程简化

因为我们比较熟悉需求获取,所以这里暂且略过。架构编排中的“编排”一词非常类似于“组织”的动词形式。不过,“组织”一词更强调人与人之间的关系和互动,因此在本书中涉及社会或企业时将使用“组织”,而涉及架构时将使用“编排”。同时,笔者会用“组织”进行类比,以加深读者对架构编排的理解。对社会组织来说,它的运转核心是“实体+规则”,其中实体可以是人、公司等,规则负责将实体有序地组织起来。例如,家庭依赖亲情关系来组织,陌生人之间则依赖法律和道德来组织。

架构编排由“架构元素+架构规则”的二元组构成。架构元素可能是应用、服务器节点、限界上下文、类等,而架构规则负责将多个元素有序地编排在一起。例如,在DDD中,多个限界上下文按照一定的规则编排起来就形成了某一个领域或子领域;多个应用按照一定的规则编排起来就是应用架构的分层视图;多个服务器节点按照一定的规则编排起来可能就实现了高并发或者高可用;而多个类编排起来可能就形成了模块或DDD中的聚合等。

显然,需求获取和架构编排是架构设计的两个重要知识领域,但是它们所代表的知识均在某一个时间节点产生作用,是相对静态的知识领域在架构设计中还存在着另一类知识,从时间维度上看,它们需要跨越一定的时间周期才能发挥作用,例如敏捷、DevOps、持续集成、持续交付、迭代、重构、系统/模型的演进等,属于动态的知识领域。因此,在架构知识模型中,还需要加入架构演进这一概念。

再回头看“需求获取”这个概念。从定义上看,它属于一个单向过程。然而,在架构设计中,需求获取并不是单向的,而是需要多方通过充分沟通才能获得的。此外,在架构设计的各个阶段,需求还会映射到业务模型、应用模型、数据模型、技术模型、类图模型、活动模型等,即在架构设计的不同阶段,都涉及不同类型信息的沟通与获取,并转化成另一种信息(模型)之后传递给下一个阶段。

因此,在建立架构知识模型时,使用“信息交换”来替代“需求获取”更加合适。信息交换可以涵盖信息获取、信息沟通和信息传递等含义。总而言之,信息交换主要指的是在架构设计过程中,不同阶段信息的输入以及模型结果的转化、输出和传递等。所以,经过上述推导,我们最终得到了以下架构知识模型:

架构知识模型=信息交换+架构编排+架构演进

此外,软件系统研发的目的是什么?它一定是为了满足客户的需求而存在的。因此,接下来从客户对系统期望的角度出发,再来审视架构知识模型是否涵盖了重要的部分。

从客户侧考虑,对软件系统的期望通常包括以下几个主要方面:功能符合预期、低成本/交付速度快以及需求可修改。其中,功能符合预期主要是指信息交换方面。低成本/交付速度快对应的主要是架构编排,所以架构编排的本质是为了实现降本增效。而需求可修改对应的则主要是架构演进。

总体来说,将架构知识模型化主要带来两个好处:一是将架构知识分类后便于厘清知识边界;二是相同分类下的架构知识往往蕴含着相似或相同的规则,方便关联记忆。

例如,DDD中的限界上下文及其关系,应用架构中的应用及其关系,面向对象编程中的类之间的关系等,都属于架构编排范畴。虽然这些概念来自不同的领域,但是它们在拆分和交互时均采用了相似或者相同类型的规则,例如高内聚、低耦合等,在后面的章节也会讲到很多类似的案例。