这是一本被前辈称赞, 另一个马丁的知名著作, 被赋予学习如何写出漂亮代码的教皇级手册, 最近(再)浏览, 有诸多感受.

总结一下就是如果你是新手, 可能看优秀的open source学习更好; 如果你是老手, 可能他说的东西要么你会觉得太啰嗦, 要么你会觉得例子太细节, 太教条, 无法举一反三.

不过一些General的要点思想我摘录了出来, 有些还包括个人的观点, 记录在此, 以备查阅.

  • 勒布朗(LeBlanc)法则, Later equals never
  • 代码如果烂了就会越来越烂, 所谓破窗原理, 以前老是也提过叫代码腐化
  • 命名
    • 命名应该合理, 成员变量不用加前缀, 靠高亮就很好
    • 接口加前缀I也不太好, 不如实现加Imp
    • 方法命名最好使用动词或动词短语
    • 多使用计算机领域的词汇
    • 有时候命名在语境里才有意义, 有时候变量命名也不需要重复语境
  • 函数
    • 函数短小一些比较易懂, 20行内最佳
    • if/else/while代码块封装函数, 只有一行最好 (有点激进?)
    • 一个函数只干一件事情
    • 复杂的switch试图用多态取代, 然后封装在抽象工厂里
    • 同一类型函数命名风格应该一致, 使用描述性的语句描述比难懂的短词更好
    • 一元函数最普遍, 标识函数(参数为boolean)的不如分成两个函数, 二元函数尽可能转换成一元函数
    • 参数太多可能需要封装类了
    • 好名字的函数一般是动词, 或者动词+关键字
    • 函数一般要么做事, 要么回答事, 不可兼得 (其实也不一定, 比如很多返回boolean状态的函数)
    • 推荐使用异常代替错误代码
    • 最好将try/catch单独抽入一个函数 (如Android代码会对RemoteService调用进行类似封装, 吃掉exception)
    • 使用枚举表示错误码会让改动变得繁琐 (重新导入或者编译部署), 大家都依赖这个枚举, 应该用异常与继承取代
    • 不要重复, 偶尔可以考虑AOP这类的方法解决
  • 注释
    • 注释少要比注释多有用, 注释多说明代码糟糕 (其实分情况吧)
    • 有目的性的注释还是有用的, 比如阐述, 放大, 警告, 定期维护的TODO等
    • 如果代码不用, 不要注释掉, 直接删掉
  • 格式
    • 横向, 竖向对齐, 间隔, 缩进等. 其实目前formater已经很强大了, 养成良好的format习惯, 渐渐的写出来的代码就会像直接format后一样
  • 对象与数据结构
    • 面向过程与面向对象对立, 前者容易加函数, 不容易加对象, 后者容易加对象, 而不容易加函数
    • 理想情况下, Law of Demeter认为, 类不应该操作对象内部的东西, 如不应该操作函数返回对象的方法. 目的只是为了降低复杂度, 认为这样将私有变量公开化, 增加了重构的难度, 如添加新函数, 方法等, 将数据结构与对象逻辑耦合在一起.
    • 针对于上面的问题, 原则应该是对象暴露行为, 隐藏数据, 数据结构暴露数据
  • 错误处理
    • Java特色的受控异常(Checked Exception), 必须得被catch, 对受控异常的修改会引起上层所有调用方法的改动, 尽量不要使用, 其他语言只有RuntimeException
    • 可以包装第三方逻辑, 封装自己的异常类, 简化为只catch一种异常
    • 简化使用也可以将异常处理完全封装进去, 返回特例即可
    • 轻易不要返回null, 传入null
    • 代码的坚固与干净不冲突, 所以添加一些check, throw相应的Exception也合理
  • 边界
    • 所谓边界就是自己可以控制到的程序与第三方的边界, 通常需要通过封装的办法来划清边界, 限制那些无法控制的第三方, 如直接Wrapper或者Adapter模式等
  • 单元测试
    • 测试需要整洁, 需要跟随代码一起更新, 测试的最大用途是保证你后续的修改有信心
    • 测试的整洁主要讲的是可读性, 即分为三个环节, build->operate->check, 可以把繁杂的准备封装起来
    • 测试API是渐渐重构演进过来的, 也不可能是起初就设计出来
    • 有人建议每个测试一个assert, 但是这样会有很多重复的代码, 不过可以利用Template Method来解决. 不过也不一定必须一个, 做到最小化就可以了
    • 整洁还有五条规则, Fast, Independent, Repeatable, Self-Validation, Timely
    • 这里讲到TDD的好处, 主要是帮助你覆盖更多的测试, 如果写完再测, 发现测不了, 就不写了.
    • 类应该短小, 权责应该足够单一, 内聚性应该高
    • 如果期望抽走一部分逻辑, 最好连相关函数参数也抽走
    • 简化类的过程应该小步, 每一步都运行测试一下
    • 类的精简是为了更好的体现开闭原则, 整体结构为修改而设计
    • 类应依赖于接口, 不依赖实现, 可以隔离修改, 符合依赖倒置原则, 类似策略模式
  • 系统
    • 构造与使用分开, 通过依赖注入等
    • 通过AOP, Proxy的方式, 无侵入性的插入逻辑
    • 系统如果充分模块化, 领域之间相互直接松耦合, 最为理想, 就可以通过测试来驱动
    • DSL的使用可以平衡领域与技术
  • 迭代
    • 代码是在不断迭代中进步的, 比如通过抽函数, 运用设计模式等
  • 并发
    • 应该尽可能分离并发代码与其他代码
    • 尽可能让线程之间独立, 不要有共享
    • 线程模型有典型的生产者与消费者, 读者与作者, 宴席哲学家模型, 分别用来说明互斥, 读写, 竞争死锁等特例
    • 锁定代码块应该尽可能小
    • 线程最好可插拔, 遵循单一权责, 分离线程与其他代码, 测试先保证除线程之外的逻辑
    • 最后一张通过实例来介绍并发代码如何重构的比较清晰
  • 逐步改进
    • 这片使用了一个例子, 先采用蛮干进行重构发现越来越难, 后来采用逐步的办法, 还写的很细节, 但是比较Tricky的地方是, 这里提出的每步改动都通过测试来印证, 然后保证测试通过, 或者补充一个测试, 让代码通过, 但是所谓TDD部分只有思想, 老代码既然写的不好, 测试是如何出来的, 如何做到Cover全的. 如果假设在一个有比较好测试覆盖的基础上重构, 我感觉即便蛮力也不会太差...
  • JUnit
    • 比较神奇的一章, 感觉更像是用一个算法类的重构来说明如何把代码改简单, 但是开头先介绍了100%覆盖的Junit测试长什么样子... 感觉作者是想说以前的人做的还不错, 都用JUnit给覆盖全了, 还是可以重构的更漂亮的, 所以感觉标题不太好
  • 重构SerialDate
    • 跟上一个对比, 这个测试覆盖不全, 所以在补测试的过程中进行重构, 还发现了缺陷, 又最终把代码改清晰了. 不过同样由于太过细节, 一些重构理论也很教条, 如果想通过看别人重构的例子来学习如果写简洁的代码, 不如直接看优秀的代码是怎么写的
  • 味道
    • 里面类比了很多Bad Smell, 同样是很细节, 比如太多, 太死, 太复杂, 重复, 不一致, 耦合, 测试不足等, 提供的Tips大多的中心思想就是抽, 封装, 单一职责, 命名清晰
    • 提到使用*来避免过长import, 不过这个与现在流行的lint检测违背, 可以因为以前都是手动, 通配符简单吧.
    • 不要通过继承来使用常量, 还提到不要用静态常量, 用枚举, 这个也与当前的思想有出入, 现在经常将Java的enum太冗余, 不必要时可以用常量

Refresh Clean Code的更多相关文章

  1. Writing Clean Code 读后感

    最近花了一些时间看了这本书,书名是 <Writing Clean Code ── Microsoft Techniques for Developing Bug-free C Programs& ...

  2. 说说怎么写clean code

    前两天参加了公司组织的一个培训,主题是“如何写出好的代码” ,刚看到这个主题,第一反应是又不知道是哪个培训机构来忽悠钱的!老大安排了,就去听听呗. 说实在的,课程内容没有什么新鲜的东西,就是讲讲如何发 ...

  3. 小课堂week13 Clean Code Part2

    Clean Code Part2 对象与数据结构 首先让我们进行一个严肃的思考,对象与数据结构的区别在哪里? 如下两段代码分别用数据结构和对象的方法来描述了一个Point. public class ...

  4. 小课堂Week12 Clean Code Part1

    小课堂Week12 Clean Code Part1 今天的主题是函数,让我们看一个函数,找一找其中的"不整洁". 我们也根据这段代码,讨论下对于整洁代码的两个重要原则. publ ...

  5. “Clean Code” 读书笔记序

    最近开始研读 Robert C.Martin 的 “Clean Code”,为了巩固学习,会把每一章的笔记整理到博客中.而这篇博文作为一个索引和总结,会陆续加入各章的笔记链接,以及全部读完后的心得体会 ...

  6. Clean Code–Chapter 7 Error Handling

    Error handling is important, but if it obscures logic, it's wrong. Use Exceptions Rather Than Return ...

  7. Clean Code – Chapter 4: Comments

    “Don’t comment bad code—rewrite it.”——Brian W.Kernighan and P.J.Plaugher The proper use of comments ...

  8. Clean Code – Chapter 3: Functions

    Small Blocks and Indenting The blocks within if statements, else statements, while statements, and s ...

  9. Writing clean code is what you must do in order to call yourself a professional.

    Clean Code  A Handbook of Agile Software Craftsmanship

  10. 《Clean Code》 代码简洁之道

    作者介绍 原文作者: Robert C. Martin, Object Mentor公司总裁,面向对象设计.模式.UML.敏捷方法学和极限编程领域的资深顾问,是<敏捷软件开发:原则.模式.与实践 ...

随机推荐

  1. vue运行时报错Error from chokidar

    原文博客地址 Error from chokidar (/home/youyou/文档/vue/vuetask01/node_modules/lodash): Error: ENOSPC: Syste ...

  2. Golang使用Gin-swagger搭建api文档

    前提是安装好了go环境与vscode环境 并配置过了gin 项目结构 1.先安装swaggo依赖包 //1 go get "github.com/swaggo/files" //2 ...

  3. mysql-对应删除 dict 脚本

    -- 1. 此 dict 是在不同租户下的数据字典,查询时需要根据 departid 进行分类查询 -- 2. 删除dict, dict分类主表类型与挂载的子表数据 -- 3. 通过查询到的主表的 g ...

  4. java中StringBuffer与 StringBuilder 类

    目录 创建 StringBuffer 类 追加字符串 替换字符 反转字符串 删除字符串 StringBuffer 方法 在 Java 中,除了通过 String 类创建和处理字符串之外,还可以使用 S ...

  5. 二进制文件分析工具-hexdump使用指南

    一 概念: hexdump是Linux下的一个二进制文件查看工具,它可以将二进制文件转换为ASCII.八进制.十进制.十六进制 格式进行 查看. 二 用法简介: 该工具的用法十分简单,具体如下所示: ...

  6. python 音频通道分离的源码实现

    一 前记 作为一个音频工程师,仅仅依靠鼠标点击,没有一些自己的小工具的话,肯定是不合格的了. 最近用到了一个音频通道分离的功能,这里就用python敲击了一下,这里做个备忘吧,给有需求的小伙伴抛砖引玉 ...

  7. pyecharts + Django你不知道这个架构有多美

    pyecharts + Django你不知道这个架构有多美 何为echarts?   pyecharts 是一个用于生成 Echarts 图表的类库.Echarts 是百度开源的一个数据可视化 JS ...

  8. Android7.0以上的分享图片文件错误及解决方法

    原文地址: Android7.0以上的分享图片文件错误及解决方法 - Stars-One的杂货小窝 在Android7.0以上版本,分享图片文件出现了exposed beyond app throug ...

  9. Github+picGo搭建图床(搭配Typora)

    使用Github+picGo搭建图床,保姆级教程来了 - 转载自知乎 (zhihu.com) 1. 注册一个Github账号 首先你需要一个github账号,如果没有的话,先注册. github官网地 ...

  10. 高级java进阶之类的卸载

    首先来了解一下jvm(java虚拟机)中的几个比较重要的内存区域 方法区:在java的虚拟机中有一块专门用来存放已经加载的类信息.常量.静态变量以及方法代码的内存区域,叫做方法区. 常量池:常量池是方 ...