整洁代码之道 2 有意义的命名

软件中随处可见命名,所以命名的规范性至关重要

2.1 介绍

  1. 做好各种命名,是整洁代码的第一步

2.2 名副其实

  1. 变量、函数或类的名称应该已经答复了所有问题 ,如果没有满足这个条件,说明这段代码不够整洁

2.2.1 Bad Example

  1. 这段代码在算法上并没有什么问题,即没有混乱的格式,也没有复杂的表达式
  2. 但即使如此简短的代码,在仔细阅读过后,也无法准确得知其用处
  3. 这就是下面这个例子的问题所在:代码中变量、函数的名称都不具备任何意义,这导致了代码的模糊度极高
public List<int[]> getThem() {
  List<int[]> list1 = new ArrayList<int[]>;
  for (int[] x : theList) {
    if (x[0] == 4) {
      list1.add(x);
    }
  }

  return list1;
}

2.2.2 Good Example

  1. 这段稍加优化后的代码,依旧没有一行注释
  2. 但在稍加阅读后,就可以得知这段代码的用处是要从棋盘中获取被标记的单元格
  3. 优化后的代码,其实没有修改任何代码逻辑,只是单纯的替换掉了变量和函数的名称
  4. 这足以说明 有意义的命名 对一段代码的重要性
public List<int[]> getFlaggedCells() {
  List<int[]> flaggedCells = new ArrayList<int[]>;
  for (int[] cell : gameBoard) {
    if (cell[STATUS_VALUE] == FLAGGED) {
      flaggedCells.add(cell);
    }
  }

  return flaggedCells;
}

2.2.3 Great Example

  1. 进一步将可能导致语义不清的数组、常量用对象替换,即可以让代码进入更高的层次
  2. 这其实已经到了重构的范畴
public List<Cell> getFlaggedCells() {
  List<Cell> flaggedCells = new ArrayList<Cell>;
  for (Cell cell : gameBoard) {
    if (cell.isFlagged()) {
      flaggedCells.add(cell);
    }
  }

  return flaggedCells;
}

2.3 避免误导

  1. 必须避免留下隐藏代码本意的错误线索
  2. 应当避免使用与代码本意相悖的词
  3. 不要使用变量类型来作为变量的名称
    • accountList 应该写成 accounts
    • Tips:不过其实我觉得如果是将其他类型转化为 String 类型使用,在名称后面加一个 Str 倒是个不错的选择
      • Date createTime 写成 createTimeStr
      • int[] codes 写成 codeStrs
  4. 不要使用相似度太高的名称,这样反而更难以区分

2.4 做有意义的区分

  1. 如果变量、函数的名称必须不同,那么两者的意思也应该不同才对
  2. 首先要做到不要用数字或废话命名,数字很好懂,那么废话是什么?
    • ProductInfoProductData 中的 InfoData ,相对于 Prodcut 本身就是废话
    • 因为这根本就是一种没意义的区分
  3. 要区分名称,就要以读者能够鉴别不同之处的方式来区分

2.5 使用读的出来的名称

  1. 人类进化到大脑中有那么大的一块地方用来处理语言,若不善加利用,实在是种耻辱
  2. 意思就是要多记单词,要不然等到给变量、函数或类命名的时候就只能使用自造词了

2.6 使用可搜索的名称

  1. 单字母名称和数字常量有个问题,就是很难再一大篇文字中找出来
  2. 名称长短与其作用域大小相对应,例如使用在 for 循环中的下标变量,使用 i 、j 或 k ,就无伤大雅

2.7 避免使用编码

  1. 这一点我觉得也不一定,例如在前端的常量 JS 中,使用 ERROR_CODE_404 以及 ERROR_CODE_400 就可以很好的区分
  2. 不过肯定也有更好的命名方法,例如根据 404 和 400 的具体含义来命名为 NO_PAGEBAD_REQUEST

2.7.1 匈牙利标记法

  1. 就是将数据类型标记在名称上
  2. 现在不论是对于 Java 还是 Javascript ,都不推荐了

2.7.2 成员前缀

  1. 应当把类和函数做的足够小,消除对成员前缀的需要

2.7.2.1 Bad Example

  1. 随着代码中名称前缀的增多,最终人们会学会无视前缀,所以前缀实际上就是毫无意义的内容
public class Part {
	private String m_dsc;

  void setName(String name) {
    m_dsc = name;
  }
}

2.7.2.2 Good Example

  1. 直接使用有意义的名称,同时遵循 Getter/Setter 规则进行赋值
public class Part {
	private String description;

  void setDescription(String description) {
    this.description = description;
  }
}

2.7.3 接口和实现

  1. 例如接口 UserService 的实现类是 UserServiceImpl

2.8 避免思维映射

  1. 名称的指向应该明确,明确是王道
  2. 专业程序员善用其能,编写其他人能理解的代码

2.9 类名

  1. 类名和对象应该是名词或名词短语
    • 例如:Customer 、WikiPage
  2. 类名不应该是动词
    • 例如:Go 、Run

2.10 方法名

  1. 方法名应该是动词或动词短语
  2. 并且依据 Javabean 标准为访问器 、修改器或断言增加 get 、set 或 is 前缀

2.11 别扮可爱

  1. 如果名称太耍宝,那就只有同作者一般有幽默感的人才能记得住
  2. 要记住 言到意到,意到言到

2.12 每个概念对应一个词

  1. 给每个抽象概念选一个词,让它能直接表达你的想法
  2. 现在的各种 IDE 都能做到直接展现某个对象能调用的方法列表,但是不难发现这些方法列表中是不会显示每个方法对应注释的
    • 所以最直接的的理解方法含义的方式,就是为方法指定一个直观的名称
    • 当然,每个方法的注释依旧还是要写的

2.13 别用双关语

  1. 避免将同一单词用于不用目的
  2. 我们想要那种大众化的平装书模式,不想要那种学者挖地三尺才能明白的学院派模式

2.14 使用解决方案领域名称

  1. 对于针对场景的变量、函数或类,优先选择通用的技术性的名称

2.15 使用源自所涉问题领域的名称

  1. 如果无法找到通用的技术性的名称,则优先选择针对场景自身最适用的名称
  2. 要做到 分离解决方案领域和问题领域 的概念

2.16 添加有意义的语境

  1. 良好命名的类、函数和变量之间应该形成一个关联关系

2.17 不要添加没用的语境

  1. 只要短名称足够清楚,就应该优先使用短名称,精确才是命名的要点

2.18 最后的话

  1. 勇敢的去重构
发布了418 篇原创文章 · 获赞 47 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/asing1elife/article/details/102874053