架构简洁之道有感,谈谈软件组件聚合的张力

配图由腾讯混元助手生成
这篇文章介绍了软件架构设计中组件设计思想,围绕“组件间聚合的张力”这个有意思的角度,介绍了概念,并且结合架构设计示例对这个概念进行了进一步阐述。
组件聚合?张力?这标题,有种字都认识,但连在一起就看不懂的感觉。但别着急,往下看就知道了。
虽然类似的思想我们可能也都看过,或者已经在使用了,但我觉得这个描述很有意思,还是花点时间再记录下。
什么是软件组件
组件是软件的部署单元,是整个软件系统在部署过程中可以独立完成部署的最小实体。
组件聚合或者拆分的基本原则
芒格给自己的投资活动列了一些基本原则,每次投资活动时都会搬出来,作为一个检查清单,来审视投资活动。
组件设计上,以及之前软件模块设计上,这些设计原则也是类似作用。当我们做架构设计时,可以把这些原则搬出来对比看看。
三个与构建组件相关的基本原则:
1.REP:复用/发布等同原则 软件复用的最小粒度应等同于其发布的最小粒度。不遵守的话,组件可能很难被复用。
2.CCP:共同闭包原则 将由于相同原因而修改,并且需要同时修改的东西放在一起。将由于不同原因而修改,并且不同时修改的东西分开。不遵守的话,即使简单的变更可能都会影响到许多组件。
3.CRP:共同复用原则 不要强迫一个组件的用户依赖他们不需要的东西。不遵守的话,可能会引起很多不必要的发布。
什么叫组件聚合的张力
上述三个原则之间彼此存在着竞争关系。REP和CCP原则是黏合性原则,它们会让组件变得更大,而CRP原则是排除性原则,它会尽量让组件变小。软件架构师的任务就是要在这三个原则中间进行取舍。
这是一张组件聚合三大原则的张力图,图的边线所描述的是忽视对应原则的后果。

只关注REP和CRP的软件架构师会发现,即使是简单的变更也会同时影响到许多组件。相反,如果软件架构师过于关注CCP和REP,则会导致很多不必要的发布。
优秀的软件架构师应该能在上述三角张力区域中定位一个最适合目前研发团队状态的位置,同时也会根据时间不停调整。
例如在项目早期,CCP原则会比REP原则更重要,因为在这一阶段研发速度比复用性更重要。一般来说,一个软件项目的重心会从该三角区域的右侧开始,先期主要牺牲的是复用性。然后,随着项目逐渐成熟,其他项目会逐渐开始对其产生依赖,项目重心就会逐渐向该三角区域的左侧滑动。
换句话说,一个项目在组件结构设计上的重心是根据该项目的开发时间和成熟度不断变动的,我们对组件结构的安排主要与项目开发的进度和它被使用的方式有关,与项目本身功能的关系其实很小。
说两个事例
单体服务与微服务
后端服务架构上的单体服务和微服务就是类似的。早期功能还不那么复杂,这时候搞个单体服务就够用;随着业务规模扩大和需求增加,这时候单体服务的缺点也暴露出来,可能一点微小的变更都需要进行全局发布,这时候就拆分成了多个微服务。

最近刚好看到一篇腾讯文档的文章《回归单体成为潮流?腾讯文档如何实现灵活架构切换》。
腾讯文档在 C 端场景中,以微服务的形式部署在 TKEx 平台上;而在私有化场景,将微服务合并成少数几个单体服务。

腾讯文档的这个自动化操作还是挺有意思。不过本质上它的组件还是拆开的,只是在部署形态上合在一起了。
控制面与转发面分离
我自己最近一个项目中,也有类似的示例。初期设计的是网关-控制器的架构,这里的网关既承担了控制面的功能,又负责转发面的事情,在初期没什么问题。可随着业务需求的发展,控制面和转发面都加了越来越多的功能,这时候团队考虑转控分离,控制面独立出一个agent来交付,网关单纯负责转发面事务。这样的好处也显而易见,避免频繁的变更,也起到了爆炸隔离的效果。
小结
回过头来看,大家其实或多或少都接触过这些思想。只是bob大叔用了张力这个表述,足够骚气。领教了。
IoT小能手twowinter的其他精彩文章:
* 动手创造
13块钱DIY微信小程序远程浇花神器
自制一个 LoRa PM2.5 监测器
语音控制智能家居的抽风小仓鼠
* 技术分享
LoRaEdge LR1120 卫星直连通信解读
深度报道 第1个从太空发回的LoRa信号(含视频)
无线节点的空中唤醒技术解析
* 多元学习
文档啊,最重要的还是层次感
你没中过勒索病毒,不知道备份有多重要
相关文章:
架构简洁之道有感,谈谈软件组件聚合的张力
配图由腾讯混元助手生成 这篇文章介绍了软件架构设计中组件设计思想,围绕“组件间聚合的张力”这个有意思的角度,介绍了概念,并且结合架构设计示例对这个概念进行了进一步阐述。 组件聚合?张力?这标题,有种…...
计算机网络 网络层上 | IP数据报,IP地址,ICMP,ARP等
文章目录 1 网络层的两个层面2 网络协议IP2.1 虚拟互联网络2.2 IP地址2.2.1 固定分类编址方式2.2.2 无分类编制CIDR2.2.3 MAC地址和IP地址区别 2.3 地址解析协议ARP2.3.1 解析过程 2.4 IP数据报格式 3 IP层转发分组流程4 国际控制报文协议ICMP4.1 ICMP格式结构4.2 分类4.2.1 差…...
金智融门户(统一身份认证)同步数据至钉钉通讯录
前言:因全面使用金智融门户和数据资产平台,二十几个信息系统已实现统一身份认证和数据同步,目前单位使用的钉钉尚未同步组织机构和用户信息,职工入职、离职、调岗时都需要手工在钉钉后台操作,一是操作繁琐,二是钉钉通讯录更新不及时或经常遗漏,带来管理问题。通过金智融…...
服务器RAID配置及功能介绍
服务器RAID配置及功能介绍 一、RAID磁盘阵列详解1.RAID磁盘阵列介绍2.RAID 03.RAID14.RAID35.RAID56.RAID67.RAID 10总结阵列卡介绍 一、RAID磁盘阵列详解 1.RAID磁盘阵列介绍 ①是Redundant Array of lndependent Disks的缩写中文简称为独立冗余磁盘阵列。 ②把多块独立的物…...
vue + element 实现鼠标左右滑动效果
我用了element中的走马灯+overflow-x: auto; html (复制后格式化一下) <div class"scroll" id"entrance"><el-carousel height"150px" :autoplay"false" :loop"false" arrow&q…...
gitlab 安装
1.安装依赖 sudo apt updatesudo apt-get upgradesudo apt-get install curl openssh-server ca-certificates postfix安装gitlab curl -s https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash官网下载安装包 要选ubuntu focal 安…...
idea中定时+多数据源配置
因项目要求,需要定时从达梦数据库中取数据,并插入或更新到ORACLE数据库中 1.pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-…...
Python---多任务的介绍
1. 提问 利用现学知识能够让两个函数或者方法同时执行吗? 不能,因为之前所写的程序都是单任务的,也就是说一个函数或者方法执行完成另外一个函数或者方法才能执行,要想实现这种操作就需要使用多任务。 多任务的最大好处是充分利用CPU资源&…...
Kubernetes 的用法和解析 -- 4
一.Deployment 资源详解 如果Pod出现故障,对应的服务也会挂掉,所以Kubernetes提供了一个Deployment的概念 ,目的是让Kubernetes去管理一组Pod的副本,也就是副本集 ,这样就能够保证一定数量的副本一直可用,…...
【fabrc.js】 操作鼠标自由绘制图形:矩形、圆形、直线等图形【画图功能】
前言: 在图形编辑器类型的项目当中,通过键盘触发想要绘制的图形类型,然后通过鼠标在fabric画布上自由绘制你想需要的内容。从画基本的矩形、圆形、直线、文本、三角形、折线等功能中,可以扩展出“钢笔path贝塞尔路径”、“多图形组…...
WPF 显示PDF、PDF转成图片
1.NuGet 安装 O2S.Components.PDFView4NET.WPF 2.添加组件 工具箱中,空白处 右键,选择项 WPF组件 界面,选择NuGet安装库对面路径下的 O2S.Components.PDFView4NET.WPF.dll 3.引入组件命名空间,并使用 <Windowxmlns"htt…...
CODESYS的Robotics_PickAndPlace_without_Depictor例程解释
1.简介 在CODESYS的例程中,有一个例程演示了如何控制delta机械手从一个移动的转盘中拾取一个工件(ring,圆环),然后放到移动的传送带上的托盘(cone,圆锥)中。这个例程在【C:\Program…...
通过全流量分析Web业务性能好坏
随着全球商业环境的不断发展和变化,业务性能的重要性愈发凸显。无论是传统实体企业还是纯线上企业,业务性能都是其核心竞争力和稳定运营的关键要素。良好的业务性能不仅可以提升客户满意度、增加市场份额,还可以降低成本、提高效率。 本文章…...
【C语言】自定义类型——枚举、联合体
引言 对枚举、联合体进行介绍,包括枚举的声明、枚举的优点,联合体的声明、联合体的大小。 ✨ 猪巴戒:个人主页✨ 所属专栏:《C语言进阶》 🎈跟着猪巴戒,一起学习C语言🎈 目录 引言 枚举 枚举…...
大模型自定义算子优化方案学习笔记:CUDA算子定义、算子编译、正反向梯度实现
01算子优化的意义 随着大模型应用的普及以及算力紧缺,下一步对于计算性能的追求一定是技术的核心方向。因为目前大模型的计算逻辑是由一个个独立的算子或者说OP正反向求导实现的,底层往往调用的是GPU提供的CUDA的驱动程序。如果不能对于整个计算过程学习…...
【密码学基础】Diffie-Hellman密钥交换协议
DH介绍 Diffie-Hellman密钥协议算法是一种确保共享密钥安全穿越不安全网络的方法。 这个机制的巧妙在于需要安全通信的双方可以用这个方法确定对称密钥,然后可以用这个密钥进行加密和解密。 但是注意,这个密钥交换协议 只能用于密钥的交换,而…...
最新AI绘画Midjourney绘画提示词Prompt教程
一、Midjourney绘画工具 SparkAi【无需魔法使用】: sparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的…...
AI助力DevOps新时代
根据2023年Gitlab全球DevSecOps报告,62%使用AI和ML的开发人员表示他们正在使用AI来检查代码,而2022年这一比例只有51%。 人工智能在 DevOps 中的作用 虽然今年年初,随着GPT的爆火,AI技术逐渐深入人心,但在很早以前&…...
Spring之容器:IOC(2)
学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您: 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持,想组团高效学习… 想写博客但无从下手,急需…...
Spring 依赖查找知识点总结
前言 源码在我github的guide-spring仓库中,可以克隆下来 直接执行。 我们本文主要来介绍依赖查找的使用示例 依赖查找 什么是依赖查找 依赖查找并不是 Spring 框架特有的概念,它是一种在软件开发中获取依赖对象的方式。它通常用于获取运行时需要的服…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
