软件复杂度
最近阅读了<结构 领域驱动设计> 针对里面的一些细节做了一些读后感
计算机编程的本质就是控制复杂度 - Brian Kernighan
(反正我也不认识,就引用下)
什么是系统复杂度
专门从事复杂系统研究的学着在接受杂志访问时,”勉为其难”的为复杂系统给出了一个相对通俗的定义:
由大量相互作用的部分组成的系统.与整个系统比起来,这些组成的部分相对简单,没有中央调度和控制,组成部分之间也没有全局性的通信,并且组成部分的相互作用导致了复杂行为.
软件复杂度的特征
对于软件复杂度的特征.基于力度的不同可以是函数,类,模块,组件,服务等维度,这些都可以算是软件元素.这些软件元素单看相对简单,而彼此之间的相互作用却导致了软件系统的复杂行为.
从软件系统的复杂度上,我们可以通过 理解能力维度 和 预测能力维度 来分析复杂度的成因.
理解能力维度
理解能力维度 - 简单的 和 复杂的
规模
软件的需求决定了系统的规模
- 1000行代码一定比100行代码复杂
- 这个服务有500个函数一定比100个函数的服务复杂
- 一个类被10个方法引用一定比被一个方法引用的复杂
- 异步代码逻辑一定比同步代码逻辑复杂
- 多线程一定比单线程复杂
- 调用远程方法一定比调用本地方法复杂
- 有10个外键关联关系的表一定比没有关联关系的表复杂
- ....
虽然软件开发不受物理法则的约束,但是无法多笔来自熵的暴击.
熵是一个物理属于,他定义了一个系统的
无序总量,不幸的是,热力学法则决定了宇宙中所有的熵都会趋向于无穷大.所以领域驱动也只是减缓系统复杂度熵的增速,而非彻底解决.
熵
的结果就是技术债
,只要是在开发就无可避免存在技术债.随着需求的增加,即便每次都看似合理的设计都逃不掉技术债.<font color=red>区别就在于技术债的多少以及利息多重</font>
结构
结构 - 决定了系统复杂度的一个关键指标,结构之所以复杂,取决于质量属性
- 多级缓存方案一定比仅有本地缓存复杂
- 分布式存储一定比单一存储复杂
- 微服务后的组织架构重组一定比单体应用时的组织架构复杂
- 可伸缩扩容的分区架构一定比固定区间设计复杂
- 可靠性99.999%一定比98%复杂
- 主从架构一定比单节点的复杂
无论设计是优雅还是拙劣,系统结构都可能因为某种设计权衡而变得复杂.但是我们还是得做.
这就像人都会死,干嘛要努力的活着.
区别就是我可以主动去控制复杂度的变化,而无视这些结构复杂化,会导致偶发性的事故发生,错误的滋生,这也是一种技术债.
预测能力维度
预测能力维度 - 有序的,复杂的,混沌的
当我们掌握了事务发展的客观规律,就具备了一定对未来的预测能力.例如我能知道下一辆12号线什么时候来,但这也不是绝对的.所以影响预测能力的关键要素在于变化.对变化的应对不妥,就会导致过度设计
和设计不足
过度设计
设计软件系统时,变化让我换得换失.主要体现在如何把握系统设计的度.总觉得这也要有,那个也要有.但是又没有可靠的依据,难以说服同事观点的论据.究其根本,对于行业领域的理解是影响设计的关键因素.
在设计层面,过度的抽象会增加方案的复杂度,扩展式设计不可预知的未来做投资,一旦未来变化不符合预期,就会导致过度设计.所以对于方案的不可预测变化,首先应该保证方案的简单些.例如设计提炼接口
.
设计不足
这部分主要体现在设计人员能力不足,也就是产品经理或者业务方.本身没有明确识别出来未来的变化,或者对需求的发展方向缺乏前瞻性.所以导致整个设计比较讲话,修改的成本比较高.从而走了另外一个极端.
我曾经负责过一个网约车的项目,我们只是一层代理商.用于向我们的客户提供网约车能力.当时产品经理找了一家网约车的服务方.我们通过接口对接的方式很容易的完成了整个下单,选车,预约,支付的闭环逻辑.但是没想到的是.这家网约车的服务质量并不高.此时需要接入另外一家网约车服务商.虽然在流程上都差不多.但是对于每个城市编码的定义,订单状态的字段含义,价格的类型,甚至是经纬度的坐标系都不是统一的.这个时候的接入工作比单纯接入一家网约车更加困难.