代码精进之路读书笔记1——命名和规范

500 阅读4分钟

前言

最近在看《代码精进之路》这本书,看了前两章,关于项目工程中命名和规范的部分,觉得深以为然。之前在公司参与过一期大型项目的重构工作,感觉关于命名和规范这块确实值得写一写,因为在重构的第一期工作就是梳理函数,添加注释等之类的工作。

一、 关于命名

在程序员的工作过程中,大部分的时间在阅读和理解代码,不管是之前我们自己写的代码还是别的伙伴交接过来的项目,亦或者是合作代发的锅中,好的模块、类、函数、变量命名能够让代码的概念清晰,增加代码的可读性;相反的词不达意的命名,会分散我们有限的注意力,破坏思考的连贯性,增加额外的工作量。

1.1 有意义的命名

我觉得书中有句话写的很好“代码即文档”,可读性好的代码应该有一定的自明性,就是不需要借助注释和文档,代码本身就能显性化地表达开发者的意图。如果无法想到一个合适的名字,很可能意味着,我们对于该问题的设计和理解有问题,这时可以思考下:是不是这个函数写了太多功能?或者类的内聚性不够?

变量命名

变量名应能准确表达业务,如果一个变量需要注释来说明,那说明这个命名就有待优化了 例如:

// 表示每页数据的条数
let s;

观察上面的命名,我们只能从注释中知道变量s指的是什么。如果没有注释,阅读代码的人为了知道s的含义,就不得不去寻找它的实例以获取线索。如果我们能够按照下面这样的方式命名这个变量,阅读代码的人就能够很容易地知道这个变量的含义。

let pageSize;

这样做还有一个好处,就是在整个项目工程中,相比较于s,能更快的搜索到pageSize字段。

函数命名

函数命名要具体,空泛的命名没有意义。

例如,handleData()就不是一个好的命名,因为所有的方法都是对据的处理,这样的命名并没有表明要做的事情,相比之下,validateUserCredentials()就要好许多。函数的命名要体现做什么,而不是怎么做。假如我们将雇员信息存储在一个栈中,现在要从栈中获取最近存储的一个雇员信息,那么getLatestEmployee()就比popRecord()要好,因为栈数据结构是底层实现细节,命名应该提升抽象层次、体现业务语义。合理的命名可以使你省掉记住“出栈”的脑力步骤,你只需要简单地说“取最近雇员的信息”

类命名

类是面向对象中最重要的概念之一,是一组数据和操作的封装。对于一个应用系统,我们可以将类分为两大类:实体类和辅助类。实体类承载了核心业务数据和核心业务逻辑,其命名要充分体现业务语义,并在团队内达成共识,如Customer、Bank和Employee等。辅助类是辅佐实体类一起完成业务逻辑的,其命名要能够通过后缀来体现功能。例如,用来为Customer做控制路由的控制类CustomerController、提供Customer服务的服务类CustomerService、获取数据存储的仓储类CustomerRepository。对于辅助类,尽量不要用Helper、Util之类的后缀,因为其含义太过笼统,容易破坏SRP(单一职责原则)。比如对于处理CSV,可以这样写:

CSVHelper.parse(String);
CSVHelper.create(int []);

但是我更建议将CSVHelper拆开:

let pageSize;
CSVParser.parse(String)
CSVBuilder.create(int [])

二、命名工具

“他山之石,可以攻玉”,当你不知道如何优雅地给变量命名时,可以使用命名工具,现在项目中最常用的是使用Codelf这样的代码搜索工具。 具体网址: codelf