美文网首页
编写可维护软件的10大要则-低层级原则

编写可维护软件的10大要则-低层级原则

作者: 塞外的风 | 来源:发表于2018-10-14 16:09 被阅读0次

本篇主要总结《代码不朽 编写可维护软件的10大要则》中的低层级原则,包括如下内容:

一. 编写短小的代码单元

1. 原则:

  • 代码单元的长度应该限制在15行代码以内
  • 你应该编写不超过15行代码的单元,或者将长的单元分解成多个更短的单元,直到每个单元都不超过15行代码。
  • 该原则能提高可维护性的原因在于,短小的代码单元易于理解、测试及重用。

2. 动机:

短小的代码单元易于测试、分析、重用

  • 短小的代码单元易于测试
    一般来说,短小的代码单元可能只做一件事,而较长的代码单元会尝试做多件事,拥有单一职责的代码更易于测试。
  • 短小的代码单元易于分析
    相比代码行数较多的代码单元,分析短小单元内部原理所花费时间更少。
  • 短小的代码单元易于重用
    较长的代码单元试图提供各种具体的实现细节,或者几个功能的固定组合,因此提供的功能范围也更加特定。短小的代码单元职责相对单一,更易于重用。

3. 如何使用本原则:

  • 场景一:编写一个新的代码单元时
    编写一个新的代码单元时,绝对不要让它超过15行代码。当你写到第15行代码时,你需要开始思考如何添加下一步的功能。它真的属于你当前编写的单元,还是应该有自己的代码单元?如果单元中的代码确实超过15行,需要想办法将它变得更短。
  • 场景二:向代码单元中添加新功能时
    当你向系统添加新功能时,代码单元开始变得越来越长,需要坚持原则,绝不能超过代码行数的限制。如果超过限制,需要考虑重构代码。

使用重构来实现该原则:
1. 提取方法
2. 将方法替换为方法对象

4. 本节内容总结:

有人可能会质疑代码单元的长度限制在15行以内是否可以实现需求功能。根据SIG的代码检测分析,优秀的项目1-15行代码占比甚至会高于90%。
实际上,要求项目中每个代码单元都不超过15行也不太现实,它只是我们编写代码单元时的目标。每当超过15行时,我们要停下来思考是否必须要超过15行,有何办法可以让代码单元不超过15行。你可以先完整地实现代码单元的功能,然后再停下来思考该如何重构以缩短其长度。如此以来,不仅可以提高代码的可维护性,更能大幅提高个人的编码水平。


二. 编写简单的代码单元

1. 原则:

  • 限制每个代码单元分支点的数量不超过4个
  • 应该将复杂的代码单元拆分成多个更简单的单元,避免多个复杂的单元在一起。
  • 该原则能提高可维护性的原因在于,分支点越少,代码单元越容易被修改和测试。

2. 动机:

简单的代码单元易于修改、测试。

  • 简单的代码单元易于修改
    高复杂度的代码单元通常难以理解,更难以修改。
  • 简单的代码单元易于测试
    代码单元的分支点越多,要覆盖所有分支的测试用例就越多,难以测试。

3. 如何使用本原则:

  • 场景一:代码单元本身包含较多会增加分支点的操作符
    代码单元包含较多会增加分支点的操作符,如if、case、&&、||、while、for、for...each、catch等。这说明代码单元逻辑较复杂,需要通过提取方法来降低复杂度。

  • 场景二:处理链式条件语句
    对于链式的if-then-else语句,或者switch-case语句,每个条件都是互斥的,可以通过引入更合适的数据结构引入多态来降低复杂度。

  • 场景三:处理嵌套条件语句
    对于嵌套层级多的条件语句,可以通过卫语句 & 提取方法来降低复杂度。

4. 本节内容总结:

代码单元简单意味着代码单元分支点少,最简单的情况就是整个代码单元顺序执行,没有多余分支。每多一个分支,理解起来相当于要多“压栈”一次,编写测试代码时就需要增加一个测试用例。
圈复杂度是代码复杂性的衡量标准,理解了圈复杂度,就理解了编写简单代码的必要性。


三. 不写重复代码

1. 原则:

  • 不要复制代码。
  • 你应该编写可重用的、通用的代码,或者调用已有的代码。
  • 该原则能提高可维护性的原因在于,如果复制代码,就需要在多个地方修复bug,不仅低效,且容易出错。

重复代码的类型:

  • 1类克隆:
    含有至少6行相同代码(不包括空行和注释行)。
  • 2类克隆:
    在语法上相同的两段代码,如下述两段代码:
public void setPageWidthInInches(float newWidth) {
    float cmPerInch = 2.54f;
    this.pageWidthInCm = newWidth * cmPerInch;
    ...
}

public void setPageWidthInPoints(float newWidth) {
    float cmPerPoint = 0.03527f;
    this.pageWidthInCm = newWidth * cmPerPoint;
    //其他代码,同setPageWidthInInches中的一样
}

2. 动机:

  • 重复代码更加难以分析
    倘若问题出在有重复代码的地方,必须查找并分析所有重复的地方,增加了处理难度。

  • 代码重复更加难以修改
    重复代码中的bug会在系统中出现多次,需要修改多次才行。

3. 如何使用本原则:

  • 提取方法
  • 提取父类

具体细节可参考《重构 改善既有代码的设计》

4. 本节内容总结:

重复代码是“万恶之源”,是最大的软件质量问题,要切记不要在系统中出现重复代码。


四. 保持代码单元的接口简单

1. 原则:

  • 限制每个代码单元的参数不能超过4个。
  • 你应该将多个参数提取成对象。
  • 该原则能提高可维护性的原因在于,较少的参数可以让代码单元更容易理解和重用。

2. 动机:

保持较少的接口参数并引入合适的参数对象,能够带来很多的好处。接口参数较少的方法能够保持简单的上下文,因此更容易被人理解。除此以外,由于它们并不过于依赖来自外部的输入,所以也更易于重用和修改。

  • 短接口更易于理解和重用
    随着代码库规模的增长,核心类会逐渐成为其他代码所依赖的API。为了避免代码量的迅速膨胀以及开发速度下降,核心类必须有一个清晰、短的接口定义。

  • 短接口的方法更易于修改
    过长的接口不仅让方法变得难以理解,许多情况下还表示它承担着多重的职责。从这个角度上讲,接口长短与代码单元大小和复杂度是有关系的,即接口过长的方法更难以修改。

3. 如何使用本原则:

  • 改进数据模型
    过长的接口本身不是问题,而是实际问题的一个表现--意味着代码中可能存在着设计不合理的数据模型,或者随意的改动。可以将接口长短视为一种代码坏味道,通过它来了解是否需要改进你的数据模型。
  • 使用方法对象替换方法

4. 本节内容总结:

根据实践中的经验,将参数个数的上限设为4个是比较合理的。5个参数的方法已经开始变得难以理解,并且担负过多的职责。


五. 编写简洁的代码

1. 原则:

  • 编写简洁的代码
  • 你不应该在完成开发工作后留下代码坏味道。

2. 动机:

简洁的代码是可维护的代码。

3. 如何使用本原则

SIG从长期的咨询经验中总结出如下7条规则来避免产生最不利于可维护性的代码坏味道:

  • 不要编写单元级别的代码坏味道
    此处的单元基本指的是函数(方法)级别,要遵守这条规则,需要及时重构“坏味道”代码。

  • 不要编写不好的注释
    注释有些时候被看作是代码不好的表现。从实际经验中可以确认,行内注释通常意味着工程方案不够优雅。
    最好的选择就是使用好的命名使得代码可以自注释。

  • 不要注释代码
    不要提交被注释掉的代码,版本控制系统会保留旧代码的记录,你可以安全地删除它们。
    从原始开发人员的角度,FIXME注释及相关代码是能够理解的,但是对于新的开发人员却是一种干扰。

  • 不要保留废弃代码
    废弃代码指的是根本不会被执行或者输出被“废弃”的代码。
    废弃代码的几种形式:
    a. 注释掉的代码
    b. 方法中无法到达的代码
    c. 无用的私有方法
    d. 注释中的代码

  • 不要使用过长的标识符名称
    通常要避免使用过长的标识符名称,团队应该有一个正式的命名规范。

  • 不要使用魔术常量
    魔术常量指的是在代码中没有被清晰定义的数字或者字符串。

  • 不要使用未正确处理的异常
    3个正确处理异常的原则:
    a. 捕获一切异常
    记录下系统的失败行为,是为了了解它们产生的原因并加以改进。空的catch代码块也能够编译通过,但这是一个不好的实践行为,它没有提供任何与异常上下文有关的信息。
    b. 捕获特定异常
    为了可以追踪某些特定事件的异常,应该捕获特定的异常。不应该直接捕获Throwable、Exception、RuntimeException异常。
    c. 在展示给终端用户之前
    先将特定的异常信息转换成通用的信息。用户不应该被具体的异常信息所“打扰”,因为这会让他们感到困惑,而且也会带来安全隐患(例如提供了有关系统内部工作原理的过多信息)。

4. 本节内容总结:

实际工作中会使用更多的编码规范和质量检查规范,这7个规范仅仅是SIG团队认为对编写可维护代码最重要的几条,应该严格遵守。

相关文章

网友评论

      本文标题:编写可维护软件的10大要则-低层级原则

      本文链接:https://www.haomeiwen.com/subject/zpbooftx.html