复杂性的本质
复杂性的定义
复杂性是指与软件系统结构有关的,使人难以理解和修改系统的所有因素。
- 难以理解代码怎么工作 (理解)
- 难以在修bug时避免引入其他bug (修改)
从成本的角度上看,复杂系统小的修改需要耗费大量人力物力,而简单的系统,只需要较少的精力就能实现较大的改进
计算公式:
$$ C = \sum_{p} c_{p} t_{p} $$ 系统的总体复杂度 C 由每个部分 p 的复杂度 cp 乘以开发者在该部分花的时间比例tp上。
复杂性的表现形式
一般有3种表现形式
变更放大
一个简单的需求,需要修改多个地方的不同代码。例如:修改网页的背景色,糟糕的设计是一个网页上指定背景色,如果多个网页需要修改背景色就要改动多个网页的代码,良好的设计:集中在一个地方指定网页的背景色,所有的网页引用这个共享值。
认知负担
开发者需要了解多少知识才能完成任务。认知负担越多,意味着开发者需要花费更多的时间学习所需的信息,但这样可能会遗漏一些重要的信息,出现错误的风险也就越大。代码行数不等同于复杂性,有时候更多的代码行实现的方法,理解更加简单。
未知的未知
不清楚必须修改哪些代码才能完成任务,或者开发者必须掌握哪些信息才能完成任务。例如:网站决定使用集中变量来设置背景色,但是有几个网页需要强调色进行内容的强调,如果背景色改变,而强调色也不行改变。开发者不得不搜索网站中搜索有强调色的网页
未知的未知是最糟糕的,我们不清楚该怎么做,也不清楚解决方案是否行得通。
复杂性的原因
依赖关系
当某一段代码不能孤立地理解和修改时,就存在依赖关系。依赖关系是软件的基本组成部分,无法完全消除事实上,我们在软件设计过程中有意引人了依赖关系 每次编写一个新类,都会在该类的应用程序接口周围创建依赖关系。
模糊性
重要的信息不明显时,就会出现模糊性。例如:变量名称太笼统,没有额外的有用信息(如time),或者没有文档说明该变量的单位。在许多情况下,模糊性是文档不足造成的;但如果一个系统需要大量的文档,往往是设计不完善的表现。
复杂性是增量的
复杂性并不是由单一的灾难性错误造成的,而是由许多小问题累积而成的。复杂性一旦起来就像很难消除,因此为了减缓复杂性,我们必须零容忍