配图由腾讯混元助手生成
这篇文章介绍了软件架构设计中组件设计思想,围绕"组件间聚合的张力"这个有意思的角度,介绍了概念,并且结合架构设计示例对这个概念进行了进一步阐述。
组件聚合?张力?这标题,有种字都认识,但连在一起就看不懂的感觉。但别着急,往下看就知道了。
虽然类似的思想我们可能也都看过,或者已经在使用了,但我觉得这个描述很有意思,还是花点时间再记录下。
什么是软件组件
组件是软件的部署单元,是整个软件系统在部署过程中可以独立完成部署的最小实体。
组件聚合或者拆分的基本原则
芒格给自己的投资活动列了一些基本原则,每次投资活动时都会搬出来,作为一个检查清单,来审视投资活动。
组件设计上,以及之前软件模块设计上,这些设计原则也是类似作用。当我们做架构设计时,可以把这些原则搬出来对比看看。
三个与构建组件相关的基本原则:
1.REP:复用/发布等同原则 软件复用的最小粒度应等同于其发布的最小粒度。不遵守的话,组件可能很难被复用。
2.CCP:共同闭包原则 将由于相同原因而修改,并且需要同时修改的东西放在一起。将由于不同原因而修改,并且不同时修改的东西分开。不遵守的话,即使简单的变更可能都会影响到许多组件。
3.CRP:共同复用原则 不要强迫一个组件的用户依赖他们不需要的东西。不遵守的话,可能会引起很多不必要的发布。
什么叫组件聚合的张力
上述三个原则之间彼此存在着竞争关系。REP和CCP原则是黏合性原则,它们会让组件变得更大,而CRP原则是排除性原则,它会尽量让组件变小。软件架构师的任务就是要在这三个原则中间进行取舍。
这是一张组件聚合三大原则的张力图,图的边线所描述的是忽视对应原则的后果。
只关注REP和CRP的软件架构师会发现,即使是简单的变更也会同时影响到许多组件。相反,如果软件架构师过于关注CCP和REP,则会导致很多不必要的发布。
优秀的软件架构师应该能在上述三角张力区域中定位一个最适合目前研发团队状态的位置,同时也会根据时间不停调整。
例如在项目早期,CCP原则会比REP原则更重要,因为在这一阶段研发速度比复用性更重要。一般来说,一个软件项目的重心会从该三角区域的右侧开始,先期主要牺牲的是复用性。然后,随着项目逐渐成熟,其他项目会逐渐开始对其产生依赖,项目重心就会逐渐向该三角区域的左侧滑动。
换句话说,一个项目在组件结构设计上的重心是根据该项目的开发时间和成熟度不断变动的,我们对组件结构的安排主要与项目开发的进度和它被使用的方式有关,与项目本身功能的关系其实很小。
说两个事例
单体服务与微服务
后端服务架构上的单体服务和微服务就是类似的。早期功能还不那么复杂,这时候搞个单体服务就够用;随着业务规模扩大和需求增加,这时候单体服务的缺点也暴露出来,可能一点微小的变更都需要进行全局发布,这时候就拆分成了多个微服务。
最近刚好看到一篇腾讯文档的文章《回归单体成为潮流?腾讯文档如何实现灵活架构切换》。
腾讯文档在 C 端场景中,以微服务的形式部署在 TKEx 平台上;而在私有化场景,将微服务合并成少数几个单体服务。
腾讯文档的这个自动化操作还是挺有意思。不过本质上它的组件还是拆开的,只是在部署形态上合在一起了。
控制面与转发面分离
我自己最近一个项目中,也有类似的示例。初期设计的是网关-控制器的架构,这里的网关既承担了控制面的功能,又负责转发面的事情,在初期没什么问题。可随着业务需求的发展,控制面和转发面都加了越来越多的功能,这时候团队考虑转控分离,控制面独立出一个agent来交付,网关单纯负责转发面事务。这样的好处也显而易见,避免频繁的变更,也起到了爆炸隔离的效果。
小结
回过头来看,大家其实或多或少都接触过这些思想。只是bob大叔用了张力这个表述,足够骚气。领教了。
IoT小能手twowinter的其他精彩文章:
* 动手创造
* 技术分享
LoRaEdge LR1120 卫星直连通信解读
深度报道 第1个从太空发回的LoRa信号(含视频)
* 多元学习