代码整洁之道笔记(三)

来源:互联网 发布:淘宝联盟怎么发链接 编辑:程序博客网 时间:2024/04/30 12:57
  1. C1不恰当的信息: 
    1. 让注释传达本该更好地在源代码控制系统、问题追踪系统或者任何其他记录系统中保存的信息,是不恰当的。例如修改历史记录只会用大量过时而无趣的文本搞乱源代码文件 。通常,作者、最后修改时间、SPR数等元素不该在注释中出现。注释只该描述有关代码和设计的技术性信息。但是对于一个类的注释我觉得有必要增加作者信息,特别是针对SDK,这样的话可以让人了解到谁开发的这个系统,后续维护十分有必要。
  2. C2:废弃的注释,注释很快会很快过时,最好别编写江北废弃的,如果发现废弃的注释,最好尽快更新或者删除掉。
  3. C3:冗余注释如果注释描述的是某种充分自我描述了的东西,那么注释就是多余的。例如:i++; //increment i还有一个典型的就是,除了函数签名什么都没有说的javaDoc
*@param sellRequest*@return *@throws Exception
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

注释应该谈及代码自身没有提到的东西 
1. C4:糟糕的代码值得编写的注释,就花时间写出最好的注释,别闲扯,保持简洁。 
2. C5:注释掉的代码看到被注释掉的代码会令我抓狂,谁知道它有多旧,删除掉

环境

  1. 需要多步才能实现的构建不应该从源代码控制系统中一小点一小点签出代码,不该需要一系列操作或者环境依赖搅拌才能check out出整个系统。
  2. 需要多步才能做到的测试你应该能够发出单个指令就可以运行全部的单元测试。对于Android的也要尽快搭建起来单元测试环境,这是TDD最重要的

函数

  1. 过多的参数,函数的参数应该少,没参数最好,一个次之,两个、三个再次之。三个以上的参数应该避免,或者抽成一个类。
  2. 输出参数 读者希望参数用于输入而非输出,如果函数非要修改什么东西的状态,就修改它所在的对象的状态好了。
  3. 标识参数布尔值参数大声宣告函数不止一件事。他们令人迷惑,应该消灭掉布尔值作为参数的时候,往往函数方法可以抽分为两个函数,分别处理true与false的情况。这样的话函数的SRP单一职责就很明确了
  4. 死函数就是永不会调用的函数,就应该丢弃,SVN等版本控制系统依然有它的备份,所以不用担心

一般性问题

  1. 一个源文件中从在多种语言。 当今的现代编程环境允许在单个源文件中存在多种不同语言。应该使用尽量少的语言
  2. 明显的行为未被实现遵循“最小惊异原则”函数或类应该实现其他程序员有理由期待的行为。
  3. 不正确的边界行为代码应该有正确的行为,这话看似明白。开发者往往写出他们以为能工作的函数,信赖自己的直觉,而不是努力去证明代码在所有的角落和边界情形下能正常工作。追索没中边界条件,编写测试。
  4. 忽视安全 测试的重要性在于,避免后期的大的灾难发生,而无法弥补
  5. 重复 每次看倒重复代码,就代表遗漏了抽象,重复的代码可以成为一个子程序或者是另外一个类。重复最明显的形态,就是不段看倒一样的代码,就像是ctrl+c 过来一样。较隐藏的状态在不同模块中不断重复出现,检测同一组条件的switch/case或者if/else链,可以用多态来替代。更加隐蔽的形态是采用类似算法,但是代码行不同的模块,这也是重复,可以用模板方法模式或者策略模式修正。
  6. 在错误的抽象层级上的代码高层级的概念应该确保全部放在基类,而低层级的概念放在派生类中。例如只与细节实现有关的常量、变量或者工具函数不应该出现在基类中。
  7. 基类依赖于派生类 修改
  8. 信息过多 设计良好的模块有着非常小的接口,让你能事半功倍。设计良好的接口并不提供许多需要依靠的函数,所以耦合度也较低。我们要隐藏自己的数据,隐藏我们的工具函数,隐藏常量和临时变量。
  9. 死代码死代码就是不执行的代码。可以检查不会发生的条件的if语句体找到,还有switch\case中永远不会匹配到的代码
  10. 垂直分割变量和函数应该在靠近被使用的地方定义,本地变量应该正好在其首次被使用的位置上面声明,私有函数应该在其首次被使用的位置下面定义。
  11. 混淆视听没有实现的默认构造器、没有用到的变量、从不调用的函数、没有意义的注释都是混淆视听的东西
  12. 人为耦合不相互依赖的东西不该耦合。例如普通的enum不应该在特殊类中包括,因为这样一来应用程序就要了解这些更为特殊的类。
  13. 函数名称应该表达其行为
  14. 把逻辑依赖改为物理依赖逻辑依赖举个例子,就是对于一个类A,把自己的属性作为参数传入另外一个类B,那么这个类A就对类B产生了逻辑依赖。如果类A直接调用类B的某个方法,则成为物理依赖。
  15. 避免否定性条件 否定式要比肯定式难明白一些,并且还多了一个!(非操作) 例如if(!sdcardExist())与if(sdcardNotExist())
  16. 隐蔽时序耦合 如果某些函数调用次序很重要,那么我们应该强调这种时序耦合关系。举例:我们要去聚餐,第一步 searchResteraunt()第二步 chooseTheCheapestResteraunt()第三步takeTaxiToResteraunt() 如果我们要强调它们的时序耦合关系,则可以将上一个函数的返回值作为下一个函数的参数,这样就建立了它们之间的时序关系。

名称

  1. 采用描述性名称
  2. 名称与抽象层级相符
  3. 无歧义的名称
  4. 尽可能使用标准命名法
  5. 为较大作用范围选用较长的名称

测试

  1. 测试不足一套测试应该测试到所有可能失败的东西
  2. 使用覆盖率工具
  3. 别略过小测试
  4. 被忽略的测试就是对不确定事物的疑问
  5. 测试边界条件
  6. 全面测试相近的缺陷在某个函数发现一个权限的时候,最好全面测试那个函数。
  7. 测试失败的模式有启发性
  8. 测试覆盖率的模式有启发性查看被或未被已通过的测试执行的代码,往往能发现失败的测试为何失败的线索
  9. 测试应该快速工程时间如果太过紧张,太慢的测试会被放弃掉
0 0