复杂性的本质

复杂性的定义

复杂性是指与软件系统结构有关的,使人难以理解和修改系统的所有因素。

  • 难以理解代码怎么工作 (理解)
  • 难以在修bug时避免引入其他bug (修改)

从成本的角度上看,复杂系统小的修改需要耗费大量人力物力,而简单的系统,只需要较少的精力就能实现较大的改进

计算公式:

$$ C = \sum_{p} c_{p} t_{p} $$ 系统的总体复杂度 C 由每个部分 p 的复杂度 cp 乘以开发者在该部分花的时间比例tp上。

复杂性的表现形式

一般有3种表现形式

变更放大

​ 一个简单的需求,需要修改多个地方的不同代码。例如:修改网页的背景色,糟糕的设计是一个网页上指定背景色,如果多个网页需要修改背景色就要改动多个网页的代码,良好的设计:集中在一个地方指定网页的背景色,所有的网页引用这个共享值。

认知负担

​ 开发者需要了解多少知识才能完成任务。认知负担越多,意味着开发者需要花费更多的时间学习所需的信息,但这样可能会遗漏一些重要的信息,出现错误的风险也就越大。代码行数不等同于复杂性,有时候更多的代码行实现的方法,理解更加简单。

未知的未知

​ 不清楚必须修改哪些代码才能完成任务,或者开发者必须掌握哪些信息才能完成任务。例如:网站决定使用集中变量来设置背景色,但是有几个网页需要强调色进行内容的强调,如果背景色改变,而强调色也不行改变。开发者不得不搜索网站中搜索有强调色的网页

未知的未知是最糟糕的,我们不清楚该怎么做,也不清楚解决方案是否行得通。

复杂性的原因

依赖关系

​ 当某一段代码不能孤立地理解和修改时,就存在依赖关系。依赖关系是软件的基本组成部分,无法完全消除事实上,我们在软件设计过程中有意引人了依赖关系 每次编写一个新类,都会在该类的应用程序接口周围创建依赖关系。

模糊性

​ 重要的信息不明显时,就会出现模糊性。例如:变量名称太笼统,没有额外的有用信息(如time),或者没有文档说明该变量的单位。在许多情况下,模糊性是文档不足造成的;但如果一个系统需要大量的文档,往往是设计不完善的表现。

复杂性是增量的

复杂性并不是由单一的灾难性错误造成的,而是由许多小问题累积而成的。复杂性一旦起来就像很难消除,因此为了减缓复杂性,我们必须零容忍