本章从高层次定义复杂度,识别出复杂度是系统设计的重要能力。设计一个简单的设计很难,可以先识别出设计是复杂的,然后逐步优化为一个简单的设计。
复杂度指一个让人难以理解和难以修改的系统结构(比如:难以理解一段代码的含义,难以做一点点小优化,在修改一个bug的时候,很难不保证引入另外的bug,那这个系统就是复杂的,否则就是简单的)(另外在工程实践时也要容易测试)
复杂度是软件工作者在开发阶段所经历的必然阶段,复杂度的定义如下:,即各个模块上所花费时间的总和,如果某个模块的复杂度很难消除,那么把它封装好,并且保证这个模块基本不需要修改,那么也能减少复杂度(隔离复杂模块),复杂度需要从读者角度定义,而不是作者角度
1、修改放大:牵一发而动全身
2、认知放大:一个开发者需要理解较多模块才能完成开发任务,同时这样也容易出bug,认知放大的表现形式:某个API有较多的方法实现、全局变量(如果全局变量用在了较多地方,很坑,不止显示的全局变量,还有很多诸如方法中static类型的变量,所以全局变量尽量限制在某个文件、类、方法内部),不一致性,模块间的独立性。复杂度与代码行数不一定相关
3、不知道自己不知道:当需要完成一个开发时,某些模块需要的修改不明显
上述三点中,第三点最致命,要等到上线出bug时才能意识的,唯一的解决方式是去阅读每行代码,显然不可能。
一个好的设计是系统的各个部分都一目了然,开发者对于要开发or修改的部分都很理解
两个原因:依赖、晦涩难懂
依赖指代码间隔离性不好,与其他代码关联度较高,如果一处代码被修改,其他的代码也必须修改。依赖不可避免,但是要尽可能使得依赖简单。(依赖尽量早期管理)
晦涩难懂表现为重要的信息不明显,只能阅读每一行代码,同时与依赖相关,依赖越多,也会导致晦涩难懂。
依赖导致修改放大和认知放大,晦涩难懂导致不知道自己不知道
复杂度是有一个个小的依赖和晦涩难懂累计上来,单独一个小依赖和晦涩难懂不会导致整体的复杂度。
也许在开发某个功能时,需要带来一个小依赖,在当时认为无所谓,但是如果每个功能都这样,最终将导致复杂度极具碰撞