代码整洁之道(一)

1,130 阅读5分钟

前言

读《代码整洁之道》的简单记录,方便之后快速搜索与查看,本文仅记录了我觉着比较重要且实用性比较强的一些内容。内容应该会持续更新~

整洁代码

简单的代码

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

在实际开发过程中,读代码的时间与写代码的时间比例超过10:1.所以在写代码的时候,我们一直在读旧的代码,所以易读的代码\color{#0abb3c}{易读的代码}实际上也是使之易写\color{#0abb3c}{使之易写}。编写的代码的难度,取决于读周边代码的难度,所以想轻松写代码,先让代码易读。

童子军军规

让营地比你来时更干净 这条简单的军规,应用到我们的专业领域,需要我们光把代码写好还不够,还必须时刻保持代码整洁\color{#0abb3c}{时刻保持代码整洁},如果每次签入时,代码都比签出时更加干净,那么代码就不会腐坏

有意义的命名

名副其实

注意命名,而且一旦发现有更好的名称,就换掉旧的\color{#0abb3c}{换掉旧的},变量、函数或者类的名称应该可以告诉读者。它为什么会存在\color{#0abb3c}{为什么会存在}它做什么事\color{#0abb3c}{它做什么事}应该怎么用\color{#0abb3c}{应该怎么用},如果名称还需要用户来写注释补充,那就不算名副其实。

避免误导

  • 应当避免\color{#0abb3c}{避免}使用与之相悖的词\color{#0abb3c}{相悖的词},比如: hp,aix,sco都不改被当成变量名,因为他们都是Unix平台的专有名词;例如也别用accountList来指一组账号,除非它真的是List类型,我们可以用accountGroup或者accounts来代表一组账号。
  • 避免\color{#0abb3c}{避免}使用外形相似度很高\color{#0abb3c}{外形相似度很高}的名称

做出有意义的区分

废话是一种没有意义\color{#0abb3c}{没有意义}的区分,比如有两个类,分别命名为ProductInfos和ProductData,他们的名称虽然不一样,但是意义没啥区别,info和data就像是a,an,the一样,是意义含混的废话。

使用读得出且可以快速搜索到的名称

对于单字母的名称和数字常量,在一堆代码中,就很难被找出来,

成员前缀

避免使用m_前缀来标明成员变量,我们应该把类和函数做的足够小,以消除对成员前缀的需要

接口和实现

一般怎么命名工厂和具体的类名呢?IShapeFactory和ShapeFactory吗?其实前导字母I\color{#0abb3c}{前导字母I}也算是废话文学,我们不想让用户知道我们给他们的是接口,只是想让他们知道这是一个ShapeFactory,如果在接口和实现中必须选择一个来编码,可能会选择使用ShapeFactoryImp\color{#0abb3c}{使用ShapeFactoryImp}来命名。

类名

类名和对象应该是名词或者名词短语\color{#0abb3c}{名词或者名词短语},他们不应该是动词。

方法名

方法名应该是动词或者动词短语\color{#0abb3c}{动词或者动词短语}

函数

函数是所有程序的第一组代码。所以对于函数的编写,有许多要注意的点

短小

函数不应该大到足以容纳嵌套结构,所以函数的缩进层级不该多于一层或者两层\color{#0abb3c}{不该多于一层或者两层}。这样的函数易于阅读和理解。

只做一件事

函数应该只做一件事\color{#0abb3c}{只做一件事},判断函数是否只做了一件事,就要看他能否合理得再拆出一个函数。

每个函数一个抽象层级

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

使用具有描述性的名称

别害怕长名称\color{#0abb3c}{别害怕长名称},长而具有描述性的名称,要比短而令人费解的名称好

函数参数

  1. 最理想的函数参数是0个,应该避免3个参数\color{#0abb3c}{应该避免3个参数}的出现,除非有特殊的理由,参数不易对付,他们带了太多概念性,当需要写测试用例的时候,会发现多个参数更加难以维护和测试。

  2. 避免使用标识参数\color{#0abb3c}{避免使用标识参数},比如向函数中传入布尔值,这相当于宣布本函数不止做一件事,即如果标识是true将会这样做,如果是false则会那样做!比如有个方法是render(true)会让用户费解,我们可以尝试写成两个方法renderForSuite()和renderForSingleTest()。

  3. 给函数起个好名字,可以较好的解释函数的意图,以及参数的顺序和意图。对于单参数函数,函数和参数\color{#0abb3c}{函数和参数}应该形成一种非常良好的动词/名词对\color{#0abb3c}{动词/名词对}的形式,例如,write(name),也可以把参数的名称编码成函数的名称,比如:assertExpectedEqualsActual(expected,actual) 这样可以减轻记忆参数顺序的负担。

注释

如果你发现自己需要写注释,就再想想看是否有办法翻盘,用代码来表达。注释\color{#0abb3c}{注释}其实\color{#0abb3c}{是}自己在表达能力上的失败\color{#0abb3c}{失败}

注释不能美化糟糕的代码

与其花时间编写解释你写出的糟糕代码的注释,不如花时间情理那堆糟糕的代码。

好注释(有必要的注释)

  1. 法律信息\color{#0abb3c}{法律信息},比如版权及著作权声明是必须和有理由在每个源文件的开头注释处放置的内容。
  2. 提供 基本信息的注释\color{#0abb3c}{基本信息的注释},比如解释某个抽象方法的返回值。
  3. 对意图的解释,比如提供某个决定后面的意图\color{#0abb3c}{某个决定后面的意图},用户写个循环2000次然后加一条注释解释为啥要循环这么多次
  4. 警示\color{#0abb3c}{警示},用于警示其他程序员可能会出现某种后果的注释
  5. TODO注释\color{#0abb3c}{TODO注释},是一种程序员认为应该做,但是由于某些原因目前还没有做的工作
  6. 放大\color{#0abb3c}{放大},放大某些看起来不合理之物的重要性
  7. 公共API中的Javadoc

坏注释

  1. 呐呐自语 如果你只是因为应该或者因为过程需要添加述职,那就是无谓之举,这个时候要考虑一下是否要重新审视自己的代码
  2. 多余注释
  3. 废话注释
  4. 能用函数或者变量时就别用注释
  5. 注释掉的代码,我们现在拥有的代码控制系统,所以不用担心代码的丢失,所以我们无需再用注释来标记删掉即可
  6. 函数头,短函数不需要太多描述,为只做一件事的函数选个好名字\color{#0abb3c}{选个好名字},通常要比写函数头注释好。
  7. 括号后边的注释,当出现深层的嵌套的时候,也许注释是有意义的,但是我们更希望编写短小、封装的函数,当你发现想给括号添加注释,其实应该做的是缩短函数。
  8. 循规式注释,即每个函数和变量都需要添加注释,这种规矩只会让代码变得散乱,令人迷惑不解