一、有意义的命名
1.名副其实
选个好名称要花时间,但省下来的时间比花掉的多。注意命名,一旦发现有更好的名称,就换掉旧的。
变量、函数或类的名称应该已经答复了所有的大问题,它该告诉你,它为什么会存在,它做什么事,应该怎么用。如果名称需要注释来补充,那就不算是名副其实。
int d; // elapsed time in days
int elapsedTimeInDays;
选择提现本意的名称能让人更容易理解和修改代码。
2.避免误导
程序员必须避免留下掩藏代码本意的错误线索,避免使用与本意相悖的词。比如首字母缩写命名hp;比如accountList除非是真的list类型。
3.做有意义的区分
以数字系列命名纯属误导,如a1,a2…等。完全没有提供正确信息,没有提供导向作者意图的线索。
废话命名都是冗余,如productInfo和productData,如phoneString,要体现有意义的区分。
状态值判断等应该用枚举常量来体现意图。
4.使用读的出来的名称
如果名称读不出来,讨论的时候就显得很傻。
private Date genymdhms;
private Date generationTimestamp;
5.使用可搜索的名称
对于单字母名称和数字常量,很难在一大片代码中找到。长名称胜于短名称,搜得到的名称胜于自造的,名称长度应与其作用域大小相应。
const int WORK_DAYS_PER_WEEK = 5;
6.名称前缀
代码读的越多,眼中就越没有前缀,只看到名称中有意义的部分,最终,前缀变作了旧代码不入眼的废料。如m_dsc。
7.避免思维映射
不应当让读者在脑中把你的名称翻译为他们熟悉的名称,这种问题经常出现在选择使用问题领域术语还是解决方案领域术语时。如循环变量i、j、k。
8.动静区分
类名或对象名应该是名词或名词短语,方法应当是动词或动词短语。
9.问题领域的名称
只有程序员会读你的代码,所以优先使用计算机术语来命名,其次才是采用涉及问题领域的名称。
10.有意义的语境
可以添加前缀提供语境,这些变量是更大结构的一部分。如:addrFirstName,addrLastName,addrState。
起好名字最难的地方在于需要良好的描述技巧和公用文化背景,做好命名事半功倍。
二、函数
1.短小
尽可能的短小,更方便阅读。
2.只做一件事
函数应该做一件事,做好这件事,只做这一件事。一方面使代码更容易理解,一方面复用性更强了。
3.向下规则
让代码拥有自顶向下的阅读顺序。程序就像是一系列To起头的段落,每一段都描述当前抽象层级,并引用位于下一层级的后续起头段落。
4.不要重复
重复使代码臃肿,尽可能避免重复的出现,可以提取公共代码。
三、注释
1.注释不能美化
注释的恰当用法是弥补我们在用代码表达意图时遭遇的失败。注释存在的越久,离其所描述的代码就越远,因为代码在变动,在演化,而注释不总是随之变动,所以要负责维护注释的准确。
与其花时间编写解释糟糕的代码的注释,不如花时间清理糟糕的代码。
2.好注释
- 与法律相关的注释,如:版权及著作权声明必须放在每个源文件开头,它应该指向一份标准许可或其他外部文档,而不是把所有条款放到注释中。
- 提供基本信息的注释,如:方法的参数意义。
- 对意图的解释,告诉别人想要做什么。
- 警示,用于警示其他程序员可能会出现某种后果的注释。
- todo注释,由于某些原因目前还没做的工作,后续清除todo。
四、格式
1.垂直间隔
几乎所有的代码都是从上往下读,从左往右读。每行展现一个表达式或一个句子,每组代码行展示一跳完整的思路,这些思路用空白行区隔开来。如:导入声明和每个函数之间。这条简单的规则极大地影响代码的视觉外观,每个空白行都是一条线索,表示新的独立概念。往下读代码时,你的目光总会停留在空白行之后的那一行。
2.垂直顺序
自上而下的展示函数调用依赖顺序,被调用的函数应该放在执行调用的函数下面,这样就建立了一种自顶向下贯穿代码模块的良好信息流。
3.水平格式
在需要的地方空格以及缩进。