[学习笔记] 《代码整洁之道》—第1章 整洁代码
- 编程:将需求明确到机器可以执行的细节程度 —> 代码
- 保持代码整洁:让营地比你来时更干净!
[学习笔记]《代码整洁之道》—第2章 有意义的命名
名副其实
-
说起来简单,但这是很严肃的事!
- 选个好名字要花时间,但省下更多的时间。
- 注意命名,一但发现更好的,就换掉旧的。
-
变量,函数或类的名称
- 已经答复了所有大问题
- 它为什么存在
- 它做什么事
- 应该怎么用
- 如果名称需要注释来补充,那就不算是名副其实!
- 已经答复了所有大问题
-
选择指明了计量对象和计量单位的名称,如:
int d; //消逝的时间,以日计
//更好的名称
int elapsedTimeInDays;
int daysSinceCreation;
int daysSinceModification;
int fileAgeInDays;
- 选择体现本意的名称能让人更容易理解和修改代码。
避免误导
- 必须避免留下掩藏代码本意的错误线索。
- 应当避免使用与本意相悖的词;
- 提防使用不同之处较小的名称;
- ControllerForEffectientHandingOfString 和 ControllerForEffectientHandingOfString难以快速区分。
- 拼写前后不一致就是误导
- 以同样的方式拼写出同样的概念才是信息。
做有意义的区分
-
如果程序员只是为满足编译器或者解释器的需要而写代码,就会制造麻烦!
-
如果名称必须相异,那其意思也应该不同!
-
以数字系列命名()是依义命名的对立面
-
纯属误导
-
完全没有提供正确的信息
-
完全没有提供导向作者意图的线索
public static void copyChars(char a1[], char a2[]){ for(int i = 0; i < a1.length; i++){ a2[i] = a1[i]; } } //修改后就像样许多 public static void copyChars(char source[], char destination[]){ for(int i = 0; i < source.length; i++){ destination[i] = source[i]; } }
-
-
废话是另一种没有意义的区分
- Product 类,ProductData 类, ProductInfo 类;名称虽然不同,但意思去无区别!
- 废话就是冗余。
-
要区分名称,就要以读者能鉴别不同之处的方式来区分。
使用读的出来的名称
-
人类擅长于记忆和使用单词,单词能读出来。
class DtaRcrd102{ private Date gentmdhms; private Date modymdhms; private final String pszqint = "102"; /* ... */ }; //修改后 class Customer{ private Date generationTimestamp; private Date modificationTimestamp; private final String recordId = "102"; /* ... */ };
使用可搜索的名称
-
单字母名称和数字常量,很难在一大篇文字中找出来。
- MAX_CLASSES_PER_STUDENT 很容易找;
- 数字 7 就很难找。
-
名称的长短应与其作用域的大小相对应
- 若变量或常量可能在代码中多次使用,则应赋其以便于搜索的名称;
- 窃以为单字母名称仅用于短方法中的本地变量。
for(int j=0; j<34; j++){ s += (t[j]*4)/5; } //修改后 int realDaysPerIdealDay = 4; const int WORK_DAYS_PER_WEEK = 5; int sum = 0; for(int j=0; j < NUMBER_OF_TASKS; j++){ int realTaskDays = taskEstimate[j] * realDaysPerIdealDay; int realTaskWeels = (realdays / WORK_DAYS_PER_WEEK); sum += realTaskWeeks; }
避免使用编码
- 把类型或作用域编进名称里,头然增加了解码负担。
- 不必用 m_前缀来标明成员变量。
- 应当把类做得足够小,消除对成员前缀的需要。
- ???接口和实现
避免思维映射
不应当让读者在脑海中把你的名称翻译为他们熟知的名称。
- 聪明的程序员和专业的程序员之间的区别在于
- 专业的程序员了解,明确是王道。
- 专业的程序员善用其能,编写其他人能理解的代码。
类名
-
类名和对象名应该是名词或名词短语
- 如 Customer,WikiPage,Account 和 AddressParser。
- 避免使用Manager, Processor,Data 或 Info 这样的类名。
-
类名不应该是动词
方法名
- 方法名应该是动词或者动词短语
- 如 postPayment,deletePage 或 save。
- 属性访问器、修改器和断言应该根据其值命名,依标准加上get, set 和 is 前缀。
别扮可爱
- 意到言到,言到意到,别耍宝!
每个概念对应一个词
- 给每个概念选一个词,并且一以贯之。
- 函数命名应当独一无二,而且保持一致。
别用双关语
- 避免将同一单词用于不用目的。
- 同一术语用于不同概念,基本就是双关语了。
使用解决方案领域名称
- 只有程序员才会读你的代码!
- 尽管用那些家算计科学术语、算法名、模式名、数学术语。
使用源自所涉问题领域的名称
- 如果不能用程序员熟悉的术语来命名,就采用所涉问题领域而来的名称吧。
- 优秀的程序员与设计师,其工作之一就是分离解决方案领域 和问题领域的概念。
- 与所涉问题领域更为贴近的代码,应当采用源自问题领域的名称。
添加有意义的语境
- 很少有名称是能够自我说明的——多数都不能。
- 你需要有良好命名的类、函数或名称空间来放置名称,给读者提供语境。
- 给名字条件加前缀就是最后一招。
- 可以添加前缀 addrFirstName、addrLastName、addrState等,以此提供语境。
- 更好的方案是创建名为 Address 的类。
不要添加没用的语境
- 只要短名称足够清楚,就比长名称好。
- 别给名称添加不必要的语境。
- 命名的要点就是精确。
取好名字最难的地方在于需要良好的描述技巧和共有文化背景。
参考文献
[1] Robert C. Martin 著,韩磊 译,《代码整洁之道》,北京:人民邮电出版社,2010.1(2018.9 重印), ISBN 978-7-115-21687-8。