【从零开始学架构 架构基础】四 架构设计的复杂度来源:可扩展性复杂度来源

架构设计的复杂度来源其实就是架构设计要解决的问题,主要有如下几个:高性能、高可用、可扩展、低成本、安全、规模。复杂度的关键,就是新旧技术之间不是完全的替代关系,有交叉,有各自的特点,所以才需要具体问题具体分析,基于各方考虑设计合适的架构,存在合适的架构,不存在最好的架构。这篇主要讨论可扩展性问题

复杂度来源

可扩展性是指,系统为了应对将来需求变化而提供的一种扩展能力,当有新的需求出现时,系统不需要或者仅需要少量修改就可以支持,无须整个系统重构或者重建

在软件设计领域,面向对象思想、设计模式主要被用于解决可扩展性问题。设计具备良好可扩展性的系统,有两个基本条件:正确预测变化、完美应对变化

预测变化

软件系统在发布后,还可以不断地修改和演进。这就意味着不断有新的需求需要实现。如果新需求能够少改代码甚至不改代码就可以实现。综合分析,预测变化的复杂性在于:

  1. 不能每个设计点都考虑可扩展性。如果每个点都考虑可扩展性,架构师会不堪重负,架构设计也会异常庞大且最终无法落地
  2. 不能完全不考虑可扩展性。不能完全不做预测,否则可能系统刚上线,马上来新的需求就需要重构,这同样意味着前期很多投入的工作量也白费了
  3. 所有的预测都存在出错的可能性。如果预测的事情出错,我们期望中的需求迟迟不来,甚至被明确否定,那么基于预测做的架构设计就没什么作用,投入的工作量也就白费了

针对上边这些复杂性,有个经验性的原则:只预测 2 年内的可能变化,不要试图预测 5 年甚至 10 年后的变化, 变化快的行业,能够预测 2 年已经足够了;而变化慢的行业,本身就变化慢,预测本身的意义不大,预测 5 年和预测 2 年的结果是差不多的。所以2 年法则在大部分场景下都是适用的

应对变化

即使预测的比较准了,但是系统设计的时候如何应对变化的扩展性也不是一个简单的问题,应对变化有两个方案:

1 提炼出变化层和稳定层

这种方案是:将不变的部分封装在一个独立的稳定层,将变化封装在一个变化层(也叫适配层)。这种方案的核心思想是通过变化层来隔离变化
在这里插入图片描述
无论是变化层依赖稳定层,还是稳定层依赖变化层都是可以的,需要根据具体业务情况来设计。如果系统需要支持 XML、JSON、ProtocolBuffer 三种接入方式,那么最终的架构就是“形式 1”架构;如果系统需要支持 MySQL、Oracle、DB2 数据库存储,那么最终的架构就变成了“形式 2”的架构了
在这里插入图片描述
这种方案的复杂度在于分层的拆分依据,以及各层的接口如何设计

  1. 明确变化层和稳定层如何拆分:对于哪些属于变化层,哪些属于稳定层需要明确
  2. 变化层和稳定层之间的接口如何设计:对于稳定层来说,接口肯定是越稳定越好;但对于变化层来说,在有差异的多个实现方式中找出共同点,并且还要保证当加入新的功能时,原有的接口不需要太大修改

3 提炼出抽象层和实现层

提炼出一个“抽象层”和一个“实现层”,因为抽象层的接口是稳定的不变的,我们可以基于抽象层的接口来实现统一的处理规则,而实现层可以根据具体业务需求定制开发不同的实现细节,所以当加入新的功能时,只要遵循处理规则然后修改实现层,增加新的实现细节就可以了,无须修改抽象层。典型的实践就是设计模式规则引擎

1 写 2 抄 3 重构原则

不要一开始就考虑复杂的可扩展性应对方法,而是等到第三次遇到类似的实现的时候再来重构,重构的时候采取隔离或者封装的方案

  • 1 写:最开始三方支付选择了微信钱包对接,此时不需要考虑太多可扩展性,直接快速对照微信支付的 API 对接即可,因为业务是否能做起来还不确定。
  • 2 抄:后来发现业务发展不错,决定要接入支付宝,此时还是可以不考虑可扩展,直接把原来微信支付接入的代码拷贝过来,然后对照支付宝的 API,快速修改上线。
  • 3 重构:因为业务发展不错,为了方便更多用户,决定接入银联云闪付,此时就需要考虑重构,参考设计模式的模板方法和策略模式将支付对接的功能进行封装。

开始可以写一些if语句进行分支判断,后续场景多起来后可以考虑设计模式去实现。

总结一下

结合这篇Blog,其实我感觉主要是如何在过度设计与不可扩展间去权衡。长期预测的代价和变数太多,可能在落地前业务就凉了,不做预测又可能刚开始迭代就发现难以支持。所以2年预测是一个经验值,如果到了2年业务发展的好了,会倒逼决策层给资源给钱进行架构升级,如果都用不了2年就凉了那5-10年预测就没意义了;在预测的前提下,我们在方案设计的时候是否可以考虑短、中、长三种方案,短期策略一般考虑的变化少,短视,但迅速,修改小,立竿见影。长期策略一般看重远期,但成本高很高,也很可能预测不中。综合成本情况下如果决定采用短期策略,要考虑如果预测的变化发生了,系统修改为长期策略的代价有多大(想在做前),如果可以演化切换那可以,如果成本很高甚至切换不到长期策略,就需要重新思考了;再说重构,重构应该是一个小步快跑的模式,不要一开始就过度抽象的设计去炫技,而是先实现最基本功能,然后逐步随业务迭代进行变化层隔离。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/38121.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

新书速览|Linux C与C++一线开发实践

《Linux C与C一线开发实践》 本书内容 Linux C/C编程在Linux应用程序开发中占有重要的地位,掌握这项技术将在就业竞争中立于不败之地。《Linux C与C一线开发实践》内容针对初中级读者,贴近软件公司一线开发实践。全书厚达620多页,知识点丰富…

51单片机第6步_stdlib.h库函数

本章重点学习stdlib.h库函数。 #include <REG51.h> //包含头文件REG51.h,使能51内部寄存器; #include <stdlib.h> //float atof (char *s1); //参数s1字符串可包含正负号,小数点或E(e)来表示指数部分,如123.456或123e-2; //若首字符是非数据字符,或为正负号…

[NSSCTF]-Reverse:[SWPUCTF 2021 新生赛]easyapp(安卓逆向,异或)

无壳 把后缀名改为zip&#xff0c;找到apk 查看jadx 这里调用了MainActivity的lambda$onCreate$0$MainActivity&#xff0c;然后又调用了Encoder进行异或。 exp&#xff1a; result棿棢棢棲棥棷棊棐棁棚棨棨棵棢棌 key987654321 flag for i in range(len(result)):flagchr(…

HarmonyOS开发:应用完整性校验

简介 为了确保应用的完整性和来源可靠&#xff0c;OpenHarmony需要对应用进行签名和验签。 应用开发阶段&#xff1a; 开发者完成开发并生成安装包后&#xff0c;需要开发者对安装包进行签名&#xff0c;以证明安装包发布到设备的过程中没有被篡改。OpenHarmony的应用完整性校…

关于响应式编程的理解与SpringCloudGateway的理解

关于响应式编程的理解与SpringCloudGateway的理解 一. 响应式编程与函数式编程的区别二. 响应式编程中常用的组件2.1 RxJava定义2.2 Rxjava基本概念2.3 RxJava 用法 三 SpringcloudGateway四 常见的四种限流规则 一. 响应式编程与函数式编程的区别 总的来说&#xff0c;响应式编…

GPIO和PIN

文章目录 1 GPIO和Pin1.1 GPIO和Pin基础概念1.2 GPIO输入模式1.3 GPIO输出模式1.4 GPIO的HAL库1.4.1 一些HAL库表示1.4.2 HAL库常用GPIO函数1.4.3 GPIO点亮led灯程序例子 1 GPIO和Pin 1.1 GPIO和Pin基础概念 ​ 单片机有很多的引脚&#xff0c;为了操控每一个引脚&#xff0c…

grpc学习golang版( 四、多服务示例 )

系列文章目录 第一章 grpc基本概念与安装 第二章 grpc入门示例 第三章 proto文件数据类型 第四章 多服务示例 第五章 多proto文件示例 第六章 服务器流式传输 第七章 客户端流式传输 第八章 双向流示例 文章目录 一、前言二、定义proto文件三、编写server服务端四、编写Client客…

MySQL之可扩展性(九)

可扩展性 直接连接 2.修改应用的配置 还有一个分发负载的办法是重新配置应用。例如&#xff0c;你可以配置多个机器来分担生成大报表操作的负载。每台机器可以配置成连接到不同的MySQL备库&#xff0c;并为第N个用户或网站生成报表。 这样的系统很容易实现&#xff0c;但如果…

Spring Boot集成jasypt快速入门Demo

1.什么是Jasypt&#xff1f; Jasypt&#xff08;Java Simplified Encryption&#xff09;是一个专注于简化Java加密操作的工具。 它提供了一种简单而强大的方式来处理数据的加密和解密&#xff0c;使开发者能够轻松地保护应用程序中的敏感信息&#xff0c;如数据库密码、API密…

stl的map和set

概念 map和set底层都是红黑树 set是key模型结构&#xff0c;本质就是看一个元素在不在容器中。 map是key/value结构&#xff0c;里面存了一个pair结构&#xff0c;可以通过一个值来查找另外一个值 map和set结构中遍历出来的都是有序并且去重了的&#xff0c;map和set都支持增…

Java高级重点知识点-17-异常

文章目录 异常异常处理自定义异常 异常 指的是程序在执行过程中&#xff0c;出现的非正常的情况&#xff0c;最终会导致JVM的非正常停止。Java处 理异常的方式是中断处理。 异常体系 异常的根类是 java.lang.Throwable&#xff0c;&#xff0c;其下有两个子类&#xff1a;ja…

【QT】概述|对象树模型|两种控件模式|信号和槽|lambda

目录 什么是QT 特点 QT程序 main函数 QT按钮 纯代码模式 图形化模式 对象树模型 信号和槽 连接与断开 自动连接 断开连接 信号的发射 lambda表达式 基本语法 捕获列表 Lambda表达式用于信号与槽的连接 例如 什么是QT Qt是一个跨平台的C图形用户界面应用…

办理河南公司企业信用等级3A证书流程和条件

企业信用等级3A证书属于一种荣誉资质&#xff0c;是提升企业公信力和影响力保障的一项资质。信用等级是信用 (资信)评估机构根据企业资信评估结果对企业信用度划分的等级类别&#xff0c;它反映了企业信用度的高低。AAA信用等级是一种等级划分。代指企业的信用经过行业、机构评…

零成本搭建个人图床服务器

前言 图床服务器是一种用于存储和管理图片的服务器&#xff0c;可以给我们提供将图片上传后能外部访问浏览的服务。这样我们在写文章时插入的说明图片&#xff0c;就可以集中放到图床里&#xff0c;既方便多平台文章发布&#xff0c;又能统一管理和备份。 当然下面通过在 Git…

中药材图像识别:中医与深度学习的融合(目标检测)

亲爱的读者们&#xff0c;您是否在寻找某个特定的数据集&#xff0c;用于研究或项目实践&#xff1f;欢迎您在评论区留言&#xff0c;或者通过公众号私信告诉我&#xff0c;您想要的数据集的类型主题。小编会竭尽全力为您寻找&#xff0c;并在找到后第一时间与您分享。 一、引…

flink的窗口

目录 窗口分类 1.按照驱动类型分类 1. 时间窗口&#xff08;Time window&#xff09; 2.计数窗口&#xff08;Count window&#xff09; 2.按照窗口分配数据的规则分类 窗口API分类 API调用 窗口分配器器&#xff1a; 窗口函数 增量聚合函数&#xff1a; 全窗口函数…

MySQL高级-MVCC-原理分析(RC级别)

文章目录 1、RC隔离级别下&#xff0c;在事务中每一次执行快照读时生成ReadView2、先来看第一次快照读具体的读取过程&#xff1a;3、再来看第二次快照读具体的读取过程: 1、RC隔离级别下&#xff0c;在事务中每一次执行快照读时生成ReadView 我们就来分析事务5中&#xff0c;两…

VBA代码解决方案第十五讲:如何对单元格区域进行高亮显示

《VBA代码解决方案》(版权10028096)这套教程是我最早推出的教程&#xff0c;目前已经是第三版修订了。这套教程定位于入门后的提高&#xff0c;在学习这套教程过程中&#xff0c;侧重点是要理解及掌握我的“积木编程”思想。要灵活运用教程中的实例像搭积木一样把自己喜欢的代码…

【操作系统期末速成】EP06 | 学习笔记(基于五道口一只鸭)

文章目录 一、前言&#x1f680;&#x1f680;&#x1f680;二、正文&#xff1a;☀️☀️☀️2.1 考点十四&#xff1a;同步互斥的基本概念2.2 考点十五&#xff1a;实现临界区互斥的基本方法2.3 考点十六&#xff1a;信号量的含义及常用信号量 一、前言&#x1f680;&#x1…

操作系统概论(二)

一、单项选择题(本大题共20小题&#xff0c;每小题1分&#xff0c;共20分) 在每小题列出的四个备选项中只有一个选项是符合题目要求的&#xff0c;请将其代码填写在题后的括号内。错选、多选或未选均无分。 1&#xff0e;操作员接口是操作系统为用户提供的使用计算机系统的手…