技术论-软件复杂度

部分内容可能来自网络或者由AI生成。
如有雷同,纯属巧合,仅供学习参考之用。

什么是复杂性

“这段代码逻辑是什么意思,看不懂啊,该怎么下手啊”

为什么开发一个需求的时间越来越长?

为什么定位一个问题好像越来越慢?

答案就是复杂性在不断增加

  • 《Code Complete》代码大全作者书中提到:“软件的首要技术使命:管理复杂度”。《SoftwareTools》表示:编程的本质就是控制复杂性。因为一旦软件复杂到一定的程度,超出了软件工程师维护/处理的能力,就可能引发软件危机里面的那些问题,长期无法解决这些问题,软件就会走向消亡衰败之路。
  • 《A Philosophy of Software Design》所谓复杂性,就是任何使得软件难于理解和修改的因素。
    • 如果一个软件系统是复杂的,那即使是很小的功能改进也需要耗费大量的时间
    • 如果一个软件系统是简单的,则可以用更少的时间来实现更大的改进。
  • 复杂度高的代码一定不是好代码,但复杂度低的也不一定就是好代码。
  • 复杂度守恒定律:复杂性既不能被创造也不能被摧毁,它只能转移到其他地方。

复杂度度量

  • 关于复杂的定义有很多种,其中比较有代表的是Thomas J. McCabe 在1976提出的理性派的复杂性度量,与John Ousterhout 教授提出的感性派的复杂性认知。这里不展开,感兴趣的可以搜搜,如:McCabe圈复杂度,通过多个维度来度量软件的复杂度,从而判断软件当前的开发/维护成本。
  • 也有一些插件,Code Metrics是idea上的一款插件,可以动态计算出代码的圈复杂度。

复杂表现形式

  • 随着软件复杂性的生长,引发的一系列软件开发和维护过程中的严重问题,这些问题会长期存在,并不断阻碍软件每次的功能迭代开发过程,最终拖垮软件。当你遇到以下类似的信号,就要开始警惕复杂性:
    • 软件到处都是依赖关系、调试耗时长、功能开发速度下降;
    • 软件频繁升级、代码库增加过快;
    • 软件开发成本难以控制、质量无法保证;
    • 用户对产品功能难以满足、软件产品难以维护、缺少适当的文档资料;
  • 复杂的系统往往也有一些非常明显的特征,John教授将它抽象为变更放大(Change amplification)、认知负荷(Cognitive load)与未知的未知(Unknown unknowns)这3类
    • 变更放大:看似简单的变更需要在许多不同地方进行代码修改;
      • 比较典型的代表是Ctrl-CV式代码开发,领域模型缺少内聚与收拢,当需要对某段业务进行调整时,需要改动多个模块以适应业务的发展。
      • 依赖混乱是指部分代码不能被独立地修改和理解,导致修改扩散。看似简单的需求,实际上需要在许多不同地方进行代码修改。
    • 认知负荷:开发人员需要多少知识才能完成一项任务。
      • 使用功能性框架时,我们希望它操作简单,部署复杂系统时,我们希望它架构清晰,其实都是降低一项任务所需的成本。盲目的追求高端技术,设计复杂系统,增加学习与理解成本都属于本末倒置的一种。
    • 未知的未知:必须修改哪些代码才能完成任务,或者说开发人员必须获得哪些信息才能成功地执行任务。
    • 由于代码的混乱与文档的缺失,导致你无法掌控一个xxx万行代码的应用,并且代码本身也没有明显表现出它们应该要阐述的内容。你不知道改动的这行代码是否能让程序正常运转,也不知道这行代码的改动是否又会引发新的问题。这时候我们发现,那些“上帝类”真的就只有上帝能拯救了。

为什么会产生复杂性

业务:快速扩张&停滞不前

  • 业务功能的扩张。为了业务规模的增长,我们需要增加
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值