当前位置: 首页 > news >正文

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

0896bc89d432d95e40c99054236bfc05.jpeg

配图由腾讯混元助手生成

这篇文章介绍了软件架构设计中组件设计思想,围绕“组件间聚合的张力”这个有意思的角度,介绍了概念,并且结合架构设计示例对这个概念进行了进一步阐述。

组件聚合?张力?这标题,有种字都认识,但连在一起就看不懂的感觉。但别着急,往下看就知道了。

虽然类似的思想我们可能也都看过,或者已经在使用了,但我觉得这个描述很有意思,还是花点时间再记录下。

什么是软件组件

组件是软件的部署单元,是整个软件系统在部署过程中可以独立完成部署的最小实体。

组件聚合或者拆分的基本原则

芒格给自己的投资活动列了一些基本原则,每次投资活动时都会搬出来,作为一个检查清单,来审视投资活动。

组件设计上,以及之前软件模块设计上,这些设计原则也是类似作用。当我们做架构设计时,可以把这些原则搬出来对比看看。

三个与构建组件相关的基本原则:

1.REP:复用/发布等同原则 软件复用的最小粒度应等同于其发布的最小粒度。不遵守的话,组件可能很难被复用。

2.CCP:共同闭包原则 将由于相同原因而修改,并且需要同时修改的东西放在一起。将由于不同原因而修改,并且不同时修改的东西分开。不遵守的话,即使简单的变更可能都会影响到许多组件。

3.CRP:共同复用原则 不要强迫一个组件的用户依赖他们不需要的东西。不遵守的话,可能会引起很多不必要的发布。

什么叫组件聚合的张力

上述三个原则之间彼此存在着竞争关系。REP和CCP原则是黏合性原则,它们会让组件变得更大,而CRP原则是排除性原则,它会尽量让组件变小。软件架构师的任务就是要在这三个原则中间进行取舍。

这是一张组件聚合三大原则的张力图,图的边线所描述的是忽视对应原则的后果。

3d9819ade3855a9aa97b83da753895d7.png

只关注REP和CRP的软件架构师会发现,即使是简单的变更也会同时影响到许多组件。相反,如果软件架构师过于关注CCP和REP,则会导致很多不必要的发布。

优秀的软件架构师应该能在上述三角张力区域中定位一个最适合目前研发团队状态的位置,同时也会根据时间不停调整。

例如在项目早期,CCP原则会比REP原则更重要,因为在这一阶段研发速度比复用性更重要。一般来说,一个软件项目的重心会从该三角区域的右侧开始,先期主要牺牲的是复用性。然后,随着项目逐渐成熟,其他项目会逐渐开始对其产生依赖,项目重心就会逐渐向该三角区域的左侧滑动。

换句话说,一个项目在组件结构设计上的重心是根据该项目的开发时间和成熟度不断变动的,我们对组件结构的安排主要与项目开发的进度和它被使用的方式有关,与项目本身功能的关系其实很小。

说两个事例

单体服务与微服务

后端服务架构上的单体服务和微服务就是类似的。早期功能还不那么复杂,这时候搞个单体服务就够用;随着业务规模扩大和需求增加,这时候单体服务的缺点也暴露出来,可能一点微小的变更都需要进行全局发布,这时候就拆分成了多个微服务。

ac714714d485c8d5fa1e9e62f20a8770.jpeg

最近刚好看到一篇腾讯文档的文章《回归单体成为潮流?腾讯文档如何实现灵活架构切换》。

腾讯文档在 C 端场景中,以微服务的形式部署在 TKEx 平台上;而在私有化场景,将微服务合并成少数几个单体服务。

cc898813284dfbcb301176072771c8b6.jpeg

腾讯文档的这个自动化操作还是挺有意思。不过本质上它的组件还是拆开的,只是在部署形态上合在一起了。

控制面与转发面分离

我自己最近一个项目中,也有类似的示例。初期设计的是网关-控制器的架构,这里的网关既承担了控制面的功能,又负责转发面的事情,在初期没什么问题。可随着业务需求的发展,控制面和转发面都加了越来越多的功能,这时候团队考虑转控分离,控制面独立出一个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中的走马灯&#xff0b;overflow-x: auto; html &#xff08;复制后格式化一下&#xff09; <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. 提问 利用现学知识能够让两个函数或者方法同时执行吗? 不能&#xff0c;因为之前所写的程序都是单任务的&#xff0c;也就是说一个函数或者方法执行完成另外一个函数或者方法才能执行&#xff0c;要想实现这种操作就需要使用多任务。 多任务的最大好处是充分利用CPU资源&…...

Kubernetes 的用法和解析 -- 4

一.Deployment 资源详解 如果Pod出现故障&#xff0c;对应的服务也会挂掉&#xff0c;所以Kubernetes提供了一个Deployment的概念 &#xff0c;目的是让Kubernetes去管理一组Pod的副本&#xff0c;也就是副本集 &#xff0c;这样就能够保证一定数量的副本一直可用&#xff0c;…...

【fabrc.js】 操作鼠标自由绘制图形:矩形、圆形、直线等图形【画图功能】

前言&#xff1a; 在图形编辑器类型的项目当中&#xff0c;通过键盘触发想要绘制的图形类型&#xff0c;然后通过鼠标在fabric画布上自由绘制你想需要的内容。从画基本的矩形、圆形、直线、文本、三角形、折线等功能中&#xff0c;可以扩展出“钢笔path贝塞尔路径”、“多图形组…...

WPF 显示PDF、PDF转成图片

1.NuGet 安装 O2S.Components.PDFView4NET.WPF 2.添加组件 工具箱中&#xff0c;空白处 右键&#xff0c;选择项 WPF组件 界面&#xff0c;选择NuGet安装库对面路径下的 O2S.Components.PDFView4NET.WPF.dll 3.引入组件命名空间&#xff0c;并使用 <Windowxmlns"htt…...

CODESYS的Robotics_PickAndPlace_without_Depictor例程解释

1.简介 在CODESYS的例程中&#xff0c;有一个例程演示了如何控制delta机械手从一个移动的转盘中拾取一个工件&#xff08;ring&#xff0c;圆环&#xff09;&#xff0c;然后放到移动的传送带上的托盘&#xff08;cone&#xff0c;圆锥&#xff09;中。这个例程在【C:\Program…...

通过全流量分析Web业务性能好坏

随着全球商业环境的不断发展和变化&#xff0c;业务性能的重要性愈发凸显。无论是传统实体企业还是纯线上企业&#xff0c;业务性能都是其核心竞争力和稳定运营的关键要素。良好的业务性能不仅可以提升客户满意度、增加市场份额&#xff0c;还可以降低成本、提高效率。 本文章…...

【C语言】自定义类型——枚举、联合体

引言 对枚举、联合体进行介绍&#xff0c;包括枚举的声明、枚举的优点&#xff0c;联合体的声明、联合体的大小。 ✨ 猪巴戒&#xff1a;个人主页✨ 所属专栏&#xff1a;《C语言进阶》 &#x1f388;跟着猪巴戒&#xff0c;一起学习C语言&#x1f388; 目录 引言 枚举 枚举…...

大模型自定义算子优化方案学习笔记:CUDA算子定义、算子编译、正反向梯度实现

01算子优化的意义 随着大模型应用的普及以及算力紧缺&#xff0c;下一步对于计算性能的追求一定是技术的核心方向。因为目前大模型的计算逻辑是由一个个独立的算子或者说OP正反向求导实现的&#xff0c;底层往往调用的是GPU提供的CUDA的驱动程序。如果不能对于整个计算过程学习…...

【密码学基础】Diffie-Hellman密钥交换协议

DH介绍 Diffie-Hellman密钥协议算法是一种确保共享密钥安全穿越不安全网络的方法。 这个机制的巧妙在于需要安全通信的双方可以用这个方法确定对称密钥&#xff0c;然后可以用这个密钥进行加密和解密。 但是注意&#xff0c;这个密钥交换协议 只能用于密钥的交换&#xff0c;而…...

最新AI绘画Midjourney绘画提示词Prompt教程

一、Midjourney绘画工具 SparkAi【无需魔法使用】&#xff1a; sparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的…...

AI助力DevOps新时代

根据2023年Gitlab全球DevSecOps报告&#xff0c;62%使用AI和ML的开发人员表示他们正在使用AI来检查代码&#xff0c;而2022年这一比例只有51%。 人工智能在 DevOps 中的作用 虽然今年年初&#xff0c;随着GPT的爆火&#xff0c;AI技术逐渐深入人心&#xff0c;但在很早以前&…...

Spring之容器:IOC(2)

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…...

Spring 依赖查找知识点总结

前言 源码在我github的guide-spring仓库中&#xff0c;可以克隆下来 直接执行。 我们本文主要来介绍依赖查找的使用示例 依赖查找 什么是依赖查找 依赖查找并不是 Spring 框架特有的概念&#xff0c;它是一种在软件开发中获取依赖对象的方式。它通常用于获取运行时需要的服…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...