名称命名规则-《代码整洁之道》读书笔记(一)

知识共享许可协议 版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons

原文地址:https://liujiao111.github.io/2019/06/18/clean-code/

变量命名是程序最基础的部分,也是多数人容易忽视的部分,总认为它无足轻重,事实不然,命名规范的代码能让人看起来赏心悦目、清晰明了。以下是一些在变量命名时候适合遵循的一些规则。

名副其实

变量、函数、类的名称应该能回复所有大的问题,它告诉你,它为什么存在,它做什么事,应该怎么用。如果名称需要注释来补充,那就不是名副其实
例如以下代码:

public static List<int[]> getThem(List<int[]> theList) {
        List<int[]> list1 = new ArrayList<>();
        for (int[] x : theList) {
            if(x[0] == 4) {
                list1.add(x);
            }
        }
        return list1;
    }

代码看起来很简单,也没有什么错误的地方,但是问题是代码的模糊度,具体有如下问题:

  • theList是什么;
  • theList的0下标条目的意义是什么?
  • 值4的意义是什么?
  • 我怎么使用返回的列表?
    改进:
  • 如果我们在开发一个扫雷游戏,theList代表盘面的单元格列表,那就将其改名为gameBoard
  • 0下标条目是一种状态值,4表示"已标记",只要将其改为有意义的名称,代码就会得到相当程度的改进,返回的数据也是这样
private static final int STATUS_VALUE = 0;
    private static final int FLAGGED = 4;

    public static List<int[]> getThem(List<int[]> theList) {
        List<int[]> flaggedCells = new ArrayList<>();
        for (int[] cell : theList) {
            if(cell[STATUS_VALUE] == FLAGGED) {
                flaggedCells.add(cell);
            }
        }
        return flaggedCells;
    }

还可以更进一步,不用int数组表示单元格,而是另写一个类,该类包括一个isFlagged函数,用来判断该cell是否已经标记过了。
新版本代码如下:

public static List<Cell> getThem(List<Cell> theList) {
        List<Cell> flaggedCells = new ArrayList<>();
        for (Cell cell : theList) {
            if(cell.isFlagged()) {
                flaggedCells.add(cell);
            }
        }
        return flaggedCells;
    }

对应的cell类(书中没有代码,不一定准确)

public class Cell {

    private Integer flag;

    private static final int FLAGGED = 4;
    
    public Cell(Integer flag) {
        this.flag = flag;  
    }

    private boolean isFlagged() {
        return this.getFlag() == FLAGGED;
    }


    public Integer getFlag() {
        return flag;
    }

    public void setFlag(Integer flag) {
        this.flag = flag;
    }
}

可以看出来,只要简单改一下名称,就能轻易知道发生了什么,这就是选用好名字的力量。

避免误导

  • 不使用平台里面的专有名词做变量名,如hp、aix、sco等;
  • 不用带List的名称来代表一组东西,例如accountList,用accountGroup或者bunchOfAccounts来代替,甚至accounts都更好些
  • 使用名称区分度很小的命名;
  • 名称中带有看起来比较像的字母、数字,例如字母1和大写字母O作为变量名,以及1和字母I,因为O很像0

做有意义的区分

  • 以数字系列命名,如(a1, a2, a3 …),这样的名称纯属误导
  • 废话也是一种无意义的区分,假如一个Product类里面有ProductInfo或者ProductData类,他们的名称虽然不同,但info和data的意义没有什么区分

使用读得出来的名称

单个字母和数字常量在文档中很难搜索到想要的,因为可能有很多,因此单个变量仅适用于短方法的本地变量,名称长短应与其作用域大小相对应,若变量或常量在代码中多处使用,应赋予其便于搜素的名称,如WORK_DAYS_PER_WEEK和5的区别

接口和实现

接口前面没有必要加个I来修饰

避免思维映射

除了在循环计数器之中使用i或者j,其他地方都应避免使用单字母变量来命名

类名

类名应该是名词或者名词短语,避免使用动词

方法名

方法名应该是动词或动词短语,如postPayment, deletePage或save,JavaBean中加上get, set,is 前缀

每个概念对应一个词

给每个抽象概念选一个词,并一以贯之

别用双关语

避免将同一单词用于不同目的。代码应该尽力让读者易懂,需要大众化的浅显易懂,而不是需要费劲去深挖的学院派模式

使用解决方案领域名称

尽量使用计算机科学术语,依据问题所涉及的领域来命令可不算是聪明的做法。

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

如果不能使用计算机科学领域的术语来命名,那就采用所涉及问题领域而来的名称

添加有意义的语境

多数名称都不能自我说明,反之,如果有良好命名的类、函数或名称空间来放置它们,给读者提供语境,这样能让别人更清晰。
如有一堆变量:firstName、lastName、street、houseNumber、city、state和zipcode的变量,它们放在一起时很明确是构成了一个地址,但是假如在方法中孤零零看到一个state呢?你很大概率上不会以为这是地址的一部分吧?你可以添加前缀addrFirstname、addrState等,以此提供语境,更好的方案是创建Address类。

不要添加没用的语境

比如有个GSD的应用,在其中每个类前面加个GSD前缀就是没必要的工作。

电子书免费共享:链接:
https://pan.baidu.com/s/1wvoRJGonA70J9hFn_w5jwA
提取码: 37jy

猜你喜欢

转载自blog.csdn.net/qq_34464926/article/details/92796776