- 什么是复杂性
- 难以理解或者难以修改的、系统相关的内容
- 复杂性的几个表现
- 对于一个变更,需要同时修改好几处相同的代码
- 认知负荷
- 隐式依赖
- 模块依赖错综复杂
- 未知的未知
这个问题的症结在于当出现问题时才能发现问题的所在,并且不知道修改了这个问题,是否会引起其他连锁反应。
- 造成复杂性表现的原因
- 依赖
- 模糊
在开发过程中,通常会显示得引入一些依赖,来减少系统的工作量。但是在这个过程中,同时也增加了系统的复杂性,和开发人员的认知成本。
依赖的模糊性,变量定义的模糊性等。
- 降低复杂性
- 一个模块,应该可以独立承载功能,如果需要配置参数才可以使用,会导致复杂度提升。如果需要添加配置参数,要考虑模块的消费者是否比模块的开发者更加了解使用参数的优劣
- 代码在一起还是分开
- 代码模块的过度细分,同样会增加系统的复杂性。可能遇到的问题是单纯找不到模块在哪里
- 如果代码模块之间紧密关联,就放在一起;如果各部分都不相关,就可以分开;
- 当模块合并使用时,用户并不需要关心其中涉及的细节,并且暴露的接口也需要发生变化,应该变得更加简单。
- 分隔一个方法,只有在使抽象逻辑更加清晰时,才更有意义
- 关于异常处理
- 不要抛出用户大概率无法处理的异常,可以通过内部处理的方式应对,比如内存不足可以直接让程序崩溃,比如经常遇到网络问题等,可以内置重试机制;
- 每一行对异常处理的代码,都会增加系统的复杂性
- 对于不重要的异常,可以在模块内部处理完成,对于非常重要的异常,一定要抛出,即使会增加系统的复杂性;
- 设计两次
- 设计往往会花费比较少的时间,但是实现却要花费好久,所以多花点时间在设计上;
- 无论多聪明的人,都无法一次就做到最好,多设计几次,能不断提升自己能力的边界;
- 注释的原因
- 注释可以隐藏系统的复杂性
- 软件开发往往面临时间的压力,而写注释并不会增加多少开发时间,反而会大大加强后期项目的可维护性
- 注释是一种高层次的抽象,应该描述内容,而非模仿代码结构的复述
- 变量名
- 要求精确,不要笼统
- 好的变量名,也是一种抽象,能够降低系统的复杂度
- 保持变量名一致性,能够降低阅读代码的心智负担,并且更快知晓代码的含义
- 提早写注释
- 在完成之后再写注释,往往是无法实现的理想行为
- 注释
- 尽量靠近代码,越远的注释应该越抽象
- 注释比代码更容易维护,如果有好的注释,能大大降低系统的复杂度,提升可维护性
- 一致性
- 在显而易见的位置建立一个文档来约定规范
- 通过工具的方式校验规范是否被遵守,否则无法提交代码
- 对于强制要求遵守摸个特定规范的地方,一定要有明确的注释说明(why/how)
- 如果要修改现有的规范,要有确切的理由证明比之前的规范更优(便捷性?反证法?示例?),并且清除之前的规范痕迹
能够降低开发人员的认知成本,降低犯错的概率,提供系统的可以维护性