读代码整洁之道总结

术语总结

TDD(Test Driven Development):测试驱动开发

理念总结

整洁的代码力求集中。每个函数、每个类和每个模块都全神贯注千一事,完全不 受四周细节的干扰和污染。

•    能通过所有测试; 
•    没有重复代码;
•    体现系统中的全部设计理念;
•    包括尽量少的实体,比如类、方法、函数等;

命名规则和例子
不要用专有名词
  • hp、aix和sco都不该用做变量名,因为它们都是UNIX平台或类UNIX平台的专有名称。
不要用误导性名称
  • 别用accountList来指称一组账号,除非它真的是List类型。List 一词对程序员有特殊意义。如果包纳账号的容器并非真是个List,就会引起错误的判断。所以,用accountGroup或 bunchOfAccounts,甚至直接用accounts都会好一些。
  • 如果用小写字母I和大写字母O作为变量名,尤其是在组合使用时,它们看起来完全像是数字1和0,
避免用废话或者数字区分
  • 数字系列命名(al、a2, aN),这样的名称纯属误导:完全没有提供正确信息,没有提供导向作者意图的线索。
  • 废话是另一种没意义的区分。假设你有一 个Product类。如果还有一个Productlnfo 或ProductData类,名称虽然不同,意思却无区别。Info和Data就像a、an和the一样,是意义含混的废话。
  • 如果缺少明确约定,变量moneyAmount就与money没区别,customerlnfo与customer 没区别,accountData与account没区别,theMessage也与message没区别。要区分名称,就要以读者能鉴别不同之处的方式来区分。
使用可以读得出来的名称

不要搞自造词或者缩写词,用的名称需要具有普遍性。

举个反例:程序里有genymdhms(生成日期,年、月、日、时、分、秒)的方法,有经验的开发会一眼看出这个方法是干啥的,但这读不出来,你试试读读看?听起来搞不搞笑?

以下是两个正反例子,可以自行体会。

class DtaRcrdl02 {
    private Date genymdhms; 
    private Date modymdhms; 
    private final String pszqint = "102";
} 
class Customer { 
    private Date generationTimestamp; 
    private Date modificationTimestamp;
    private final String recordid = "102"; 
}
使用可搜索的名称

长名称胜于短名称,搜得到的名称胜于用自造编代码写出的名称。名称长短应与其作用域大小相对应。

以下例子中,WORK_DAYS_PER_WEEK要比数字5好找得多,对吧?

for (int j=O; j<34; j++) { 
    s += (t[j]*4)/5; 
}

int realDaysPeridealDay = 4; 
const int WORK_DAYS_PER_WEEK = 5; 
int sum = 0; 
for (int j=O; j < NUMBER_OF_TASKS; j++) { 
    int realTaskDays = taskEstimate[j] * realDaysPeridealDay; 
    int realTaskWeeks = (realdays / WORK_DAYS_pER_WEEK); 
    sum += realTaskWeeks; 
}
避免使用编码

编码已经太多, 无谓再自找麻烦。把类型或作用域编进名称里面, 徒然增加了解码的 负担。没理由要求每位新人都在弄清要应付的代码之外(那算是正常的),还要再搞懂另一种编码 “语言”。 这对于解决问题而言,纯属多余的负担。带编码的名称通常也不便发音, 容易打错。

避免思维映射

不应当让读者在脑中把你的名称翻译为他们熟知的名称。

单字母变量名就是个问题。 在作用域较小、 也没有名称冲突时,循环计数器自然有可能
被命名为i或j或k。(但千万别用字母l!)这是因为传统上惯用单字母名称做循环计数器。

然而,在多数其他情况下,单字母名称不是个好选择;读者必须在脑中将它映射为真实概念。仅仅是因为有了a和b, 就要取名为c, 实在并非像样的理由。

专业程序员 善用其能,编写其他人能理解的代码。

类名

类名和对象名应该是名词或名词短语,如Customer、WikiPage、Account和AddressParser。 避免使用Manager、Processor、Data或Info这样的类名。类名不应当是动词。

方法名

方法名应当是动词或动词短语,如postPayment、deletePage或save。属性访问器、修改器和断言应该根据其值命名,并依Javabean标准加上get、set和is前缀。

string name = employee.getName(); 
customer.setName("mandy"); 
if (paycheck. is Posted())... 

重载构造器时,使用描述了参数的静态工厂方法名。例如,

Complex fulcrumPoint = new Complex (23. 0); 
// => 更好的写法
Complex fulcrumPoint = Complex.FromRealNumber(23.0); 

别扮可爱

扮可爱的做法在代码中经常体现为使用俗话或俚语。

如果有个函数叫HolyHandGrenade。翻译过来就是圣手手雷,虽然搞笑但不直译,改成Deleteltems跟让人一目了然。

再例如,别用whack()(whack是劈砍的意思)来表示kill()。别用eatMyShorts()(eatMyShorts是去死吧的意思)这类与文化紧密相关的笑话来表示abort()。

每个概念对应一个词

函数名称应当独一无二,而且要保持一致。反之,在同一堆代码中有controller,又有manager,还有driver,就会令人困惑。DeviceManager 和Protocol-Controller之间有何根本区别?为什么不全用controllers或managers?他们都是 Drivers吗?这种名称,让人觉得这两个对象是不同类型的,也分属不同的类。

那些会用到你代码的程序员, 一以贯之的命名法简直就是天降福音。

别用双关语

避免将同一单词用于不同目的。同一术语用于不同概念, 基本上就是双关语了。 如果遵循“一词一意”的规则,可能在好多个类里面都会有add方法。 只要这些add方法的参数列表和返回值在语义上等价, 就一切顺利。

但是, 可能会有人决定为 “保持一致” 而使用add这个词来命名, 即便并非真的想表示这种意思。比如, 在多个类中都有add方法,该方法通过增加或连接两个现存值来获得新值。假设要写个新类,该类中有一个方法,把单个参数放到群集(collection)中。该把这个方法叫做add吗?这样做貌似和其他add方法保持了一致, 但实际上语义却不同, 应该用insert 或append之类词来命名才对。把该方法命名为add,就是双关语了。

使用解决方案领域名称

只有程序员才会读你的代码。所以,尽管用那些计算机科学(Computer Science, CS) 术语、算法名、模式名、数学术语,换句话说就是程序员熟悉的术语。

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

如果不能用程序员熟悉的术语来命名,就采用从所涉问题领域而来的名称吧。 至少负责维护代码的程序员就能去请教领域专家了。如果所涉问题领域更为贴近代码, 应当采用源自问题领域的名称。

添加有意义的语境

你需要用有良好命名的类 、函数或名称空间来放置名称, 给读者提供语境。 如果没这么做,给名称添加前缀就是最后一招了。

不要添加没用的语境

比如,你在GSD应用程序中的记账模块创建了一个表示邮件地址的类,然后给该类命名为GSDAccountAddress。你的客户联络应用中需要用到邮件地址,你会用 GSDAccountAddress吗?这名字听起来没问题吗?在这17个字母里面,有10个字母纯属多余和与当前语境毫无关联。

只要短名称足够清楚,就要比长名称好。别给名称添加不必要的语境。

对于Address类的实体来说,accountAddress和customerAddress都是不错的名称,不过用在类名上就不太好了。Address是个好类名。如果需要与MAC地址、端口地址和Web地址相区别,我会考虑使用PostalAddress、MAC和URL。这样的名称更为精确,而精确正是命名的要点。 

函数
函数的第一规则是要短小

if语句、else语句、while语句等,其中的代码块应该只有一行。该行大抵应该是一个函数调用语句。这样不但能保持函数短小,而且,因为块内调用的函数拥有较具说明性的名称。函数的缩进层级不该多于一层或两层。当然,这样的函数易于阅读和理解。

函数应该做一件事。做好这件事。只做这一件事。

 要判断函数是否不止做了一件事,还有一个方法,就是看是否能再拆出一个函数,该函数不仅只是单纯地重新诠释其实现。做一件事的函数无法被合理地切分为多个区段。

要确保函数只做一件事,函数中的语句都要在同一抽象层级上。

【持续更新ing】

相关推荐

  1. 代码整洁总结

    2024-03-21 23:58:04       21 阅读
  2. Bob大叔三部曲代码整洁

    2024-03-21 23:58:04       39 阅读
  3. 前端代码整洁规范

    2024-03-21 23:58:04       30 阅读
  4. 代码整洁学习笔记

    2024-03-21 23:58:04       5 阅读
  5. 阅读笔记——《代码整洁》ch2

    2024-03-21 23:58:04       11 阅读
  6. clean code-代码整洁 阅读笔记(第九章)

    2024-03-21 23:58:04       6 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-21 23:58:04       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-21 23:58:04       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-21 23:58:04       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-21 23:58:04       20 阅读

热门阅读

  1. Python Web开发记录 Day14:Django part8 订单管理

    2024-03-21 23:58:04       18 阅读
  2. VUE tinymce editor 配置手册-封装组件

    2024-03-21 23:58:04       19 阅读
  3. 【C#】Microsoft learn入门C#教程简介

    2024-03-21 23:58:04       17 阅读
  4. 20.python——数据读取与存储

    2024-03-21 23:58:04       19 阅读
  5. macOS安装erlang以及rabbitMq详情版本

    2024-03-21 23:58:04       19 阅读
  6. rust - 对文件夹进行zip压缩加密

    2024-03-21 23:58:04       23 阅读
  7. web蓝桥杯真题:灯的颜色变化

    2024-03-21 23:58:04       22 阅读
  8. 软件测试面试接口测试常见问题

    2024-03-21 23:58:04       18 阅读
  9. 【C语言】对称密码——栅栏的加密和解密

    2024-03-21 23:58:04       16 阅读
  10. 什么是虚拟dom

    2024-03-21 23:58:04       19 阅读