命名技巧心得

654 阅读5分钟

宗旨

一个命名提供的信息量越多,就是越好的命名。

最容易的事

声明一个变量,是编程里最简单的事了。

在学习编程之初,先要会的就是声明一个变量。

int a = 1;

最困难的事

命名又是我们工作中最有难度的事。

随着我们技术能力的提高,做的项目也越来越大,业务越来越复杂。命名稍微不注意,就变成一堆无意义或者误导我们的字符串。

之所以说命名困难,我的想法是命名不单是想一个单词就ok。需要更多的理解业务,理解我们使用的技术,才能做到最贴切的命名。

信息量

回到我们的宗旨,来看看命名都会给我们提供哪些信息量。

例1

var username = '卡哇伊';

这段代码中有个变量username,它为我们提供了一个信息。

  1. 这是一个代表用户名的字段。

例2

var _username = '卡哇伊';

这段代码是有个变量_username,它为我们提供了两个信息。

  1. 这是一个代表用户名的字段。
  2. 这是一个私有变量。我们把下划线开头的变量,称为私有变量。只有类内部可以访问。

例子3

class User {
    constructor() {
        this._name = '卡哇伊';
    }
    
    getName() {
        return this._name;
    }
    
    setName(val) {
        this._name = val;
    }
}

User命名的信息

  1. 这是一个类。
  2. 用户的类。
  3. 为内部的变量提供上下文,所以用户名可以只写成_name,代表User的_name。如果还需要一个用户年龄的字段,可以只写成_age。

getName的信息

  1. 这是一个方法,由动词+名词组成。我们用动词或者动词+名词命名一个方法。因为方法本身就代表某种动作,所以这样命名很贴切。并且和类的字段(名词)做了有效的区分。这样你在其他地方使用user.get***。你就知道这是调用了user的一个方法。user.hand就是使用了user的一个字段。
  2. 拿到用户名。

读到这里,我想你大概知道我要说的什么意思了。我们通过命名的格式,用开头有下划线代表私有变量,用首字母大写代表是一个类。区分不同类型的成员,达到让代码拥有更多信息量的目的。

那么,重点就是掌握一套这样的命名规则,并严格贯彻这套规则。

工作中的实践

这里拿React写一个页面作为例子 首先我要新建一个Pages文件夹,然后新建一个ProductListPage文件夹,在里面建立index.js文件,代码如下:

class ProductListPage extends Component {

    constructor(props) {
        this.state = {
            productList:[],
            categroyOptions:[],
        }
    }
    
    componentDidMount() { ... }
    
    
    async requestProductList() { ... }
    
    async requestCategroyOptions() { ... }
    
    
    renderProductList() {
        const { productList } = this.state;
        
        return productList.map(product => { ... });
    }
    
    renderHeader() { ... }

    render() { ... }
}

Pages文件夹:

  1. 页面文件夹,为其下的文件提供上下文,我是一个放置页面文件的文件夹。
  2. 表明我在项目的的位置,项目中还可以定义其他类别的文件夹,components文件夹,reducers文件夹,共同形成项目结构。

ProductListPage:

  1. ProductListPage代表我要写一个产品列表相关的页面。
  2. Page尾缀与Pages文件夹呼应。在项目中有特殊地位的文件,加尾缀是很有用处的,比如你的代码中出现一个productListReducer变量,你就知道它来自Redcer这个特定模块。

componentDidMount:

  1. 这里着重说一下react的声明周期方法,我认为这个命名是比vue的略好一点的。==因为越是系统级别的命名,越是要详细一点==。因为系统级别的方法,用的场景多,重名的几率就大。比如vue的created生命周期方法,一个新手不知道这个方法,在写一个私有方法的时候,恰好也是创建某事物的含义,就用了creacted命名,就造成了重名。
  2. componentDidMount的component又与组件呼应。明确的告诉我们这是组件的mount。
  3. 引伸出一条规则是:越局部的变量可以越短小。它可以充分的利用上下文解释自己。

productList:

  1. 这个变量与页面名字同名,我喜欢用这种方式告诉自己,这个变量是这个页面的主角。另外List尾缀也有强调这是个重要数据的意思,配角的列表数据我都喜欢加s,比如categroyOptions。这样利用List和s区分主次关系。
  2. 在列表变量进行循环的时候,循环体中就可以用product

requestProductList:

  1. 请求产品列表。
  2. request是一个关键动词,我赋予了它特别的含义,就是需要稍微花点时间才能取到的值,与get动词对应。

renderProductList:

  1. 渲染产品列表
  2. render是一个关键动词,是react的拥有特殊含义的词,渲染页面。

嗯,每个命名都满满的信息量,我们就得到了易读又工整的代码。

规则的破坏

值得注意的是,命名是件需要自律和习惯的事。比如某一天增加了一个产品包装页,我写成了goodsPackingPage。这样‘产品’这个有特殊业务含义的字段在项目中有了两个命名,product和goods,这就造成了一定的混乱。

我见过这样一个单文件,有2000多行的代码,同样代表品类,结果有三个单词type,catagory,class。起初我以为是不同的意思,这就造成了阅读的困难。你的代码越复杂,命名不当造成的问题越严重。

所以我们在写代码时,建立的命名秩序,就不能破坏它。一旦破坏,原本可以传达的信息,便不再可信。比如新写的私有字段不以下划线开头。那么以后在函数中看到变量,就不能根据是否已下划线开头,判断它是否是私有变量了。

结束语

判断一个命名是否糟糕,就是看它有没有传达信息。更糟糕的是,它传达错误的信息。

好的命名就是能传达更多信息。依靠的是你建立的命名秩序。

如果你对整洁代码很有兴趣。推荐《代码整洁之道》这本书。里面有更多详细的关于命名的技巧知识。