代码自查

43 阅读4分钟

01 缺乏业务含义的命名

  • 不精准的命名
  • 用技术术语命名

描述意图,而非细节;

面向接口编程;

使用业务语言。

02 乱用英语

  • 违反语法规则的命名
  • 不准确的英语词汇
  • 英语单词的拼写错误
  • 使用拼音进行命名
  • 使用不恰当的单词简写(比如,多个单词的首字母,或者写单词其中的一部分)。

类名要用名词,函数名要用动词或动宾短语;

要建立团队的词汇表;

要经常进行代码评审;

编写符合英语语法规则的代码。

03 重复代码

  • 复制粘贴的代码
  • 结构重复的代码
  • if 和 else 代码块中的语句高度类似

在软件开发里,有一个重要的原则叫做 Don't Repeat Yourself(不要重复自己,简称 DRY);

在一个系统中,每一处知识都必须有单一、明确、权威地表述。

04 长函数

  • 超过20行
  • 平铺直叙写代码
  • 一次增加一点点代码

分离关注点;

把函数写短,越短越好。

05 大类

  • 职责不单一
  • 字段未分组

应对大类的解决方案,主要是将大类拆分成小类,本质上在做的是设计工作;

模块拆分,本质上是帮助人们降低理解成本的一种方式;

把类写小,越小越好。

06 长参数列表

应对长参数列表主要的方式就是减少参数的数量,一种最直接的方式就是将参数列表封装成一个类。但并不是说所有的情况都能封装成类来解决,我们还要分析是否所有的参数都有相同的变动频率。

  • 变化频率相同,则封装成一个类

  • 变化频率不同的话:

  • 静态不变的,可以成为软件结构的一部分

  • 多个变化频率的,可以封装成几个类

除此之外,参数列表中经常会出现标记参数,这是参数列表变长的另一个重要原因。对于这种标记参数,一种解决方案就是根据这些标记参数,将函数拆分成多个函数。

减小参数列表,越小越好。

07 滥用控制语句

  • 嵌套的代码
  • else 语句
  • 重复的 switch
  • 循环语句

函数至多有一层缩进;

不要使用else关键字;

多态取代条件表达式;

循环和选择语句,可能都是坏味道。

08 缺乏封装

  • 过长的消息链,连续的函数调用,把实现细节暴露了出去,缺乏应有的封装
  • 基本类型偏执,用各种基本类型处传递,这种情况下通常是缺少了一个模型

遵循迪米特法则;

封装所有的基本类型和字符串;

隐藏委托关系;构建模型,封装散落的代码。

09 可变的数据

  • 暴露细节
  • 可变的数据
  • 全局数据

限制变化;

尽可能编写不变类;

实体对象要限制数据变化,而值对象就要设计成不变类;移除设值函数(Remove Setting Method)。

10 变量声明与赋值分离

  • 变量的声明和赋值是分离的

在能够使用 final 的地方尽量使用 final,限制变量的赋值;

用声明式的方式进行集合的初始化;

一次性完成变量的初始化。

11 依赖混乱

  • 缺少防腐层,请求对象传导到业务代码中,造成了业务与外部接口的耦合
  • 业务代码中出现具体的实现类,实际上是违反了依赖倒置原则

引入防腐层,将业务与内部接口隔离;

引入模型,将业务与具体实现隔离。

12 不一致的代码

  • 命名中的不一致
  • 方案中的不一致,一方面是由于代码长期演化造成的,另一方面是项目中存在完成同样功能的程序库;
  • 代码中的不一致,把不同层次的代码写在了一起,最典型的就是把业务层面的代码和实现细节的代码混在一起。

保持代码在各个层面上的一致性。

13 落后的代码风格

  • 引入Optional,减少由于程序员的忽略而引发对空对象的问题,类似 Kotlin 的可空类型
  • 函数式编程,map、filter 和 reduce把大部分的集合操作转换成列表转换

不断学习“新”的代码风格,不断改善自己的代码。