架构整洁之道摘录
软件架构
软件架构规则和其他变量完全⽆关。
软件设计的终极⽬标是⽤最⼩的成本来满⾜构建和维护系统的需求。
程序设计重要的是软件架构的灵活性⽽不是先实现功能。
软件系统的第⼀价值体系是系统⾏为,第⼆价值体系是系统架构
编程范式
结构化编程
利⽤if/else while等替代goto的使⽤,结构化编程对程序控制权的直接转移进⾏了限制和规范。
⾯向对象编程
利⽤多态限制⽤户对函数指针的使⽤,⾯向对象编程对程序控制权的间接转移进⾏了限制和规范。
函数式编程
函数式编程⼀般不可以修改变量的值,因此函数式编程对于变量的赋值进⾏了限制和规范。
⽤顺序结构、分⽀结构和循环结构就可以构造出任何程序。
架构设计时,对于功能的降解拆分仍然很重要。
⾯向对象编程
⾯向对象编程是⼀种对真实世界进⾏建模的⽅式。
封装性对于⾯向对象编程语⾔实际是削弱了。例如c++需要将变量定义在头⽂件中,java,c#由
于没头⽂件⽽分不清申明和定义。
完美的封装性存在于c语⾔中,struct定义在其他头⽂件,使⽤时前置申明好再使⽤。
继承性
继承特性在c语⾔中通过数据结构的内部变量的顺序控制以及强制类型转换实现。但是⾯向对象
的编程语⾔还是提供了更加易⽤的使⽤⽅式,⽐如多重继承的实现以及隐式的转换。
多态性
多态性使⽤c语⾔的函数指针也可以实现,但是对于易⽤和安全上,⾯向对象编程语⾔还是更加优秀。
⾯向对象编程通过多态实现依赖反转,这样可以完全控制系统中源码的依赖关系。使得架构师可以构建出插件式架构,每个组件实现独⽴部署。
不变性
函数式编程语⾔的变量是不可变的。这主要是为了避免造成多线程、死锁、并发等等的问题。
可变性隔离
将可变的组件和不可变的组件进⾏分离,不可变的组件使⽤纯函数的⽅式来执⾏任务,期间状态不可更改。不可变的组件将通过⼀个或者多个⾮函数式组件通信的⽅式来修改状态。
状态的修改⼀般使⽤事务型内存来保护可变变量,避免同步或者竞争状态的发⽣。
⼀个架构设计良好的应⽤程序应该将状态修改的部分和不需要修改的部分隔离或者独⽴成单独的组件,然后使⽤合适的机制来保护可变量。应该将逻辑尽可能的放在不可变组件中,可变组件中的逻辑越少越好。
SOLID原则
SRP:单⼀职责原则,每个软件模块有且只有⼀个被改变的理由
任何⼀个软件模块应该只对⼀类⾏为者负责
反⾯案例:⼀个⼯资管理程序的Employee类中包含三个函数calculatePay、reportHours、save,但这三个函数不属于⼀类calculatePay是财务部⻔制定、reportHours有HR使⽤、save由DBA制定。因此解决⽅法是将不同的⾏为者进⾏切分。
OCP原则
开闭原则,软件系统想要更加容易被改变的话,就需要允许增加代码来实现模块功能⽽⾮
修改现有的代码。⼀个好的计算机软件应该易于扩展,抗拒修改。模块单向依赖,限制每次修改的影响范围。实现⽅式是通过将系统划分为⼀系列的组件,将这些组件按照层次结构进⾏划分,使得低层次组建的修改不会影响⾼层次组件。
LSP原则
⾥⽒替换原则,软件最好遵守同⼀个约定,这样组件之间可以相互替换。
⼀个类依赖于另⼀个类的⽗类,这样⼦类不同,依赖的类不需要修改。
LSP原则不仅仅适⽤于继承类型,它适⽤于所有有统⼀的接⼝,并且期望可以相互替换的接⼝。
ISP原则
接⼝隔离原则,设计中避免不必要的依赖。类与类之间依赖只涉及必要的接⼝,⽆关的接⼝
不要依赖。
DIP
依赖反转原则,⾼层策略性的代码不应该依赖底层实现的代码,反之底层实现的代码应该依赖⾼层策略性的代码对于软件系统中经常变动的模块应该提供⼀个稳定的抽象接⼝。
代码中多使⽤抽象接⼝,尽量避免使⽤那些多变的具体实现类。不要在具体实现类派衍⽣类。不要覆盖包含具体实现的函数。应避免今年在代码中写任何与具体实现有关的名字,或者其他容易变动的名字。但具体实现调⽤的组件也不是不能出现,⼀般⼀个模块中会有⼀个调⽤具体实现的main组件。
组件
组建是指在软件部署时的最⼩单元。⽆论采⽤哪种部署形式,设计良好的组件应该保持可以单独部署的属性。
重定位技术
重定位技术出现是为了解决函数需要通过源代码的形加载使⽤的代码中,并且地址固定。
通过修改程序输出⼆进制⽂件的格式,由⼀个智能加载器加载到任意的内存。程序员需要指加载到的内存位置可重定位的代码中添加了⼀些记号,加载器在加载时会对这些制定的位置进⾏⼀些修改,⼀般是递增。这样的话,程序员可以⽤加载器来修改库函数加载的位置,并且还可以同时加载多个。
链接加载器
将库中的函数存储起来,⼀段程序调⽤了库中函数会被定义为外部引⽤,并将库中函数的名字称为外部定义,将两者链接起来。这样可以让程序员实现将程序分为多个可以被分别编译的代码段。
但是对于代码量较⼤的程序来说,这个过程⾮常缓慢,因此只能将加载和链接分离。链接过程放到链接器中进⾏。
现代程序由于内存和运算速度的⼤幅提⾼,链接过程已经⼤幅减少时间。
组件的形式在动态链接⽂件加载的应⽤场景中⾮常典型。⽬前插件式的架构已经被⼴泛使⽤。
组件聚合
REP 复⽤/发布等同原则
软件复⽤的最⼩粒度等同于发布的最⼩粒度。组建中的类与模块是密切相关的。
CCP 共同闭包原则
将可能同时修改以及有相同修改⽬的的类放在⼀个组件中。
CRP 共同复⽤原则
不要强迫⽤户⽤他们不需要的东⻄
⾯向服务架构
将系统拆分为⼀个个服务,服务之间进⾏隔离。服务需要⽀持单独编译和部署。
耦合的谬论
即使拆分为每个服务,但是进程之间的通信以及共享资源还是会将服务耦合在⼀起。所以如果想做到真正的耦合需要考虑如何避免这些问题。
独⽴部署的谬论
数据形式和⾏为形式的耦合,仍然会导致独⽴部署的困难。
横跨型变更
⽐如⼀个功能变更影响到许多的服务,这样也⽆法避免逻辑耦合的服务⼀起变更。
解决横跨型问题的⼀个⽅案是采⽤⾯向对象的组件式的模型,将逻辑放在基类中,特定的功能放在⼦类中。
服务边界不能代表系统的架构边界,服务内部的组件边界才是。
测试也是⼀种系统组件
可以将测试代码视为系统最外圈的程序。始终向内依赖,但其他组件不依赖它。
为了防⽌系统组件的修改引起⼤量的测试程序改变,需提⾼系统的可测试性,原则就是尽量少的依赖多变的东⻄。
整洁的嵌⼊式架构
软件不会随着时间推移⽽磨损,但是硬件会,因此硬件变更时软件可能也需要随之变更。因此需要通过好的架构设计来避免固件更迭带来的软件不适配问题,延⻓代码的有效使⽤⽣命周期。
嵌⼊式系统设计⼀般采⽤分层的⽅法。HAL是硬件抽象层,这⼀层将会给业务提供软件接⼝,因此会对硬件进⾏抽象。HAL的上层业务不需要知道底层硬件具体的实现细节,这样测试也可以通过HAL接⼝灌⼊值对软件接⼝进⾏测试。
硬件绑定很深的代码,例如硬件⼚商提供的读写寄存器、IO中断等的代码需要限制在固件层。和软件隔离之上层业务才能做到更好的移植性和可测试性。
软件和固件之间还需要操作系统层来防⽌上层代码和操作系统产⽣依赖。
整洁的嵌⼊式架构会引⼊操作系统抽象层,OSAL兼容以前的接⼝,并且可以让应采⽤定义好的公⽤结构。OSAL还可以为应⽤提供⽬标平台外的测试⽀撑点,是的测试也不依赖操作系统。
⾯向接⼝编程与可替代性
⾯向接⼝的交互式使得服务的可替代性提⾼。⽬前的普适规则是使⽤头⽂件充当接⼝的定义,但这样的话就需要保证头⽂件内容只包括函数声明以及函数使⽤到的结体和变量。数据库
数据库终究只是在硬盘与内存之间相互传输数据的⼀种⼿段⽽已,它真的可以被认为只是⼀个⻓期存储数据的、系统架构应该对磁盘本身的存在完全不关⼼。
相关文章:
架构整洁之道摘录
软件架构 软件架构规则和其他变量完全⽆关。 软件设计的终极⽬标是⽤最⼩的成本来满⾜构建和维护系统的需求。 程序设计重要的是软件架构的灵活性⽽不是先实现功能。 软件系统的第⼀价值体系是系统⾏为,第⼆价值体系是系统架构 编程范式 结构化编程 利⽤if/else…...
流程引擎-自定义函数的应用
背景: 某些业务需求比较特殊,需要在表单中校验或实现一些功能,泛微流程表单配置时实现的方式多种多样:JS脚本、SQL语句、公式以及其他一些标准化拖拽功能,本次给大家分享一下流程表单中的公式实现的一些需求场景。泛微…...
ChatGLM系列二:ChatGLM2的介绍及代码实践
一、介绍 2023年06月25日,清华大学开源了 ChatGLM2-6B 模型,是 ChatGLM 模型的升级版本。ChatGLM2-6B 在多个方面有显著提升:模型性能更强,在各种测试集上的表现更好;支持更长的上下文,最大上下文长度提升…...
JDBC对数据库进行操作
一.使用JDBC查询数据库表t_user的所有数据 1.User表 名称 数据类型 主键 是否为空 说明 ID number 是 用户编号 NAME Varchar2(50) 用户名 AGE varchar2(5) 用户年龄 BIRTH date 用户生日 PWD varchar2(20) 否 用户密码 import java.sql.Connection; import java.sql.Date; …...
unity 使用Image的RectTransform来进行判断是否点击到
public RectTransform LeftTouchArea;public RectTransform RightTouchArea;private void Update(){if (Input.GetMouseButtonDown(0)){//获取鼠标的位置Vector2 mousePos Input.mousePosition;//判断Image的坐标是否包含点击的坐标if (RectTransformUtility.RectangleContain…...
【C++】类与对象 第一篇(class,this)
目录 什么是类? 类的引入 class 类的两种定义方式: 声明与定义分离 类的访问限定符号 访问限定符编辑 C中struct和class的区别是什么? 封装 类的作用域 类的实例化 类对象模型 如何计算类对象的大小 this指针 C语言和C实现Stack的对比 C语言实现…...
嵌入式软件工程师面试题——2025校招专题(四)
说明: 面试题来源于网络书籍,公司题目以及博主原创或修改(题目大部分来源于各种公司);文中很多题目,或许大家直接编译器写完,1分钟就出结果了。但在这里博主希望每一个题目,大家都要…...
actual combat 21——华为云从零开始项目部署(附nginx转发域名方式)
一、IP地址方式: 后端: 确保项目本地跑通建立并运行华为云流水线 前端: 打包(测试环境)手动上传 nginx: 配置一下即可 华为云: 安全组:暴露后端网关端口安全组:暴…...
@CallSuper注解方法学习
CallSuper注解是什么? CallSuper 是 Android 开发中使用的一个注解,它的主要用途是确保在子类重写父类的方法时,调用 super 方法。这在某些情况下是非常有用的,例如当你希望在重写方法时保留父类的默认行为,或者确保子…...
03_Flutter自定义下拉菜单
03_Flutter自定义下拉菜单 在Flutter的内置api中,可以使用showMenu实现类似下拉菜单的效果,或者使用PopupMenuButton组件,PopupMenuButton内部也是使用了showMenu这个api,但是使用showMenu时,下拉面板的显示已经被约定…...
如何查看多开的逍遥模拟器的adb连接端口号
逍遥模拟器默认端口号为:21503。 不过,使用多开器多开的时候,端口就不一定是21503了。 如何查看? 进入G:\xiaoyao\Microvirt\MEmu\MemuHyperv VMs路径中 每多开一个模拟器,就会多出一个文件夹。 进入你要查找端口号…...
2023年中国道路扫雪车分类、市场规模及发展前景分析[图]
道路扫雪车是一种专门用于清除道路上积雪和冰雪的机动车辆,通常配备有雪铲、扫雪刷、除冰剂喷洒系统等装置,用于在雪季或寒冷气候条件下,对道路进行清扫、除雪、除冰等作业,以确保道路的通行安全。 道路扫雪车行业分类 资料来源&…...
【机器学习】迁移学习(Transfer)详解!
1. 什么是迁移学习 迁移学习(Transfer Learning)是一种机器学习方法,就是把为任务 A 开发的模型作为初始点,重新使用在为任务 B 开发模型的过程中。迁移学习是通过从已学习的相关任务中转移知识来改进学习的新任务,虽然大多数机器学习算法都是…...
软件测试面试题
软件测试面试时一份好简历的重要性 软件的生命周期(prdctrm) 计划阶段(planning)-〉需求分析(requirement)-〉设计阶段(design)-〉编码(coding)->测试&am…...
分治算法解决归并排序问题
分治算法定义:分治算法是一种问题解决方法,它将一个大问题划分为多个相同或相似的子问题,然后递归地解决这些子问题,最后将子问题的解合并得到原问题的解 作用: 排序算法分治算法在排序算法中得到广泛应用。例如&…...
Spring Security漏洞防护—HttpFirewall和 HTTPS
一、HttpFirewall Spring Security有几个领域,你所定义的 pattern 会针对传入的请求进行测试,以决定应该如何处理请求。这发生在 FilterChainProxy 决定请求应该通过哪个过滤链时,以及 FilterSecurityInterceptor 决定哪些安全约束适用于请求…...
Makefile泛谈
Makefile工作原理 1、检查规则中的依赖文件是否存在。 2、若依赖文件不存在,则寻找是否有规则用来生成该依赖文件。 譬如,执行文件会先寻找.o文件是否存在,如果不存在,就会再寻找是否有规则可以生成该依赖文件。如果缺少了main.…...
Python的快捷键
Python Python使用的小快招关于注释关于格式写主函数如何看函数源代码 Python使用的小快招 本文主要记录了写python代码的时候提高效率的一些小妙招 关于注释 选中要注释的代码,然后按下Ctrl /即可对多段代码注释。 关于格式 对于python代码的格式,…...
css为盒子设置滚动条隐藏滚动条
省流:为盒子设置宽高,设置滚动条方向,隐藏滚动条。 首先,要为需要添加滚动条的盒子设置固定的高度和宽度,这样才能让内容超过盒子的边缘。 .box {width: 300px;height: 300px; }然后,给盒子加入overflow属…...
音视频开发常见问题(四):视频花屏和绿屏
摘要 本文介绍了视频视频花屏/绿屏问题的常见原因,如丢失关键帧、metadata的变化、硬件编解码的兼容性问题和颜色格式不一致问题。以及排查方法和解决策略,包括检查视频数据格式、排查自采集/自渲染模块问题、联系第三方音视频SDK技术支持等。最后&…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
