美文网首页
《clean code》

《clean code》

作者: EmilioWong | 来源:发表于2018-07-29 16:04 被阅读0次

本文记录阅读《clean code》的过程中一些个人收获和疑惑,持续更新ing。

一些收获

函数

  • 以下代码初看感觉挺正常的,以前也写过类似的代码。但它违反了单一职责原则和开闭原则,每次添加新类型时,就必须要修改,最麻烦得是可能还有类似的结构,如isPayday(Employee e, Date date)等。解决方法:将这些代码封装到个抽象类Employee里,子类CommissionedEmployee,HourlyEmployee等实现掉,然后由一个工厂方法构造子类。调用工厂方法获得具体引用,再调用具体的calculatePay,isPayday等方法。switch最终只出现在抽象类的工厂方法里,而且在系统其它部分看不到。
public Money calculatePay(Employee e) throws InvalidEmployeeType {
    switch (e.type) {
        case COMMISSIONED:
            return calculateCommissionedPay(e);
        case HOURLY:
            return calculateHourlyPay(e);
        case SALARIED:
            return calculateSalariedPay(e);
        default:
            throw new InvalidEmployeeType(e.type);
    }
}
  • 一元函数通常要比二元函数要好理解点,如writeField(name)比writeField(outputStream, name)好懂。可以采用一些机制把二元函数转换成一元函数。如,可以把writeField方法写成outputStream的成员之一,就能用outputStream.writeFile(name);或者可以把outputStream写成当前类的成员变量,就无需再传递;还可以分离出类似FieldWriter的新类,在其构造器中采用outputStream,并且包含一个write方法。
  • 使用异常代替错误码。错误码通常意味着有个枚举,这对增加新的错误码造成了负面压力,因为需要重新构建和部署所有东西。新异常可以从异常类派生出来,无需重新编译或重新部署。

注释

  • 别给糟糕的代码加注释----重新写吧。我自从看过《重构》之后,就比较认同这一观点:注释应该用方法名代替,如果你需要写注释,那么就是一个重构的信号了。那么哪些情况是需要注释的呢?以下是书中我比较认同的。
  1. 法律信息
  2. 对意图的解释
  3. 警示
  4. TODO
  5. 放大某些看来不合理之物的重要性。这个有点难理解,下面是原文内容。不过我觉得这个其实和“对意图的解释”有点类似。
String listItemContent = match.group(3).trim();
// the trim is real important. It removes the starting
// spaces that could cause the item to be recognized
// as another list
new ListItemWidget(this, listItemContent, this.level + 1);
return buildList(text.substring(match.end()))
  1. 公共API的javadoc(javadoc也可能存在废话。如果要求所有的变量和函数都要有注释的规则是愚蠢可笑的)
  • 坏注释
  1. 喃喃自语
  2. 多余的注释
  3. 误导性注释
  4. 循规蹈矩式注释
  5. 日志式注释
  6. 废话注释
  7. 可怕的废话(指的是javadoc)
  8. 能用函数或变量时就别用注释
  9. 位置标记(并不是所有位置标记都是烂代码,但比较容易滥用)
  10. 括号后面的注释
  11. 归属于署名(并不是@author这种,源代码控制系统是这类信息最好的归属地:svn、git等)
  12. 注释掉的代码
  13. HTML注释
  14. 非本地信息(在本地注释的上下文环境中给出系统级的信息)
  15. 信息过多
  16. 不明显的联系
  17. 函数投
  18. 非公共代码中的javadoc

对象与数据结构

  • 面向过程代码便于在不改动既有数据结构的前提下添加新函数。面向对象代码便于在不改定既有函数前提下添加新类。反过来也说得通:面向过程代码难以添加新数据结构,因为必须修改所有函数;面向对象代码难以添加新函数,因为必须修改所有类。所以,对于面向对象较难的事情,面向过程式代码却较容易,反之亦然。

一点疑惑

  • 整体看下来,本书多个地方都有强调测试的重要性。但是依我目前的工作经验来说,还没有看到一家公司是以测试驱动开发的。测试代码主要的困难点是dao的测试,api的测试,controller层的测试,这些分别可以用h2 DB,mockito,mockMvc解决。包括别的书,也一直有强调测试驱动,也许还是国内大部分程序员最早接触代码的时候,就不是以测试驱动的形式开发有关系吧,包括我本人也一样,也是不太接受测试驱动的。我自认目前对生产代码的编写习惯、风格等有了一套自我认知,但对测试代码这一块还是比较空白的。

相关文章

网友评论

      本文标题:《clean code》

      本文链接:https://www.haomeiwen.com/subject/vyazmftx.html