• Chapter 2  命名

    • 命名要表现意图
    • 避免歧义和误导,增强区分
    • 命名可读性:便于发音,增强印象,便于交流
    • 命名可查性:增强区分,便于搜索
    • 类和对象的命名:名词或名词短语
    • 方法的命名:动词或动词短语
    • 使用仅表述单一概念的词,如 get,避免多概念的词,如 fetch
    • 使用行业术语及业务术语
  • Chapter 3  方法

    • 尺寸:越小越好,不应超过20行
    • if、else、while 等 statement 不应超过一行
    • 单一责任
    • 单一抽象层级
    • 无参最优,一参数次之,二参数最次,不应超过3参数,否则应引入参数结构或对象
    • 避免将参数作为输出
  • Chapter 4  注释

    • 尽量少用注释,避免过时的注释
    • 如果能用良好的命名来表现意图,就不用注释
    • 如果能用代码来表现意图,就不用注释
    • 良好的注释: 
      • 提供补充信息
      • 解释意图
      • 警告
      • TODO 注释
      • 强调注释
  • Chapter 5  格式

    • 垂直格式:

      • 单个类文件,不超过100行/150行/200行
      • 使用空行分隔方法
      • 自顶向下的方法依赖分布
    • 水平格式
      • 单行不超过80字符/100字符/120字符,屏幕能够全部显示
      • 保持缩进
      • 使用空格,运算符左右使用空格等
      • 显式地突出空循环,避免省略地写为一行
      • 优先遵循团队规定的格式
  • Chapter 6  对象和数据结构

    • 数据结构和对象的对立性:

      • 数据结构以 public 暴露内部属性,不提供访问方法
      • 对象以 private 隐藏内部属性,提供访问方法
      • 数据结构易于增加新方法,同时不影响已有结构。对象反之,易于增加新类,同时不影响已有方法。
      • 数据结构不便于增加新数据结构,因为需要改变每个已有方法。对象反之,不便于增加新方法,因为需要改变每个已有类。
      • Law of demeter:最少知识原则,一个对象应对其他对象有尽量少的了解。类C的 f 方法,应只调用这些方法:
        • 类C的方法
        • f 创造的对象的方法
        • 传递给 f 的参数对象的方法
        • 类C的成员实例变量的方法
  • Chapter 7  错误处理

    • 使用 exception, 避免使用返回的错误码
    • 逐层 throw exception,在最顶层 catch,即定义一个错误传递流
    • 将 try/catch 抽取出来作为独立函数
    • 在需要时定义新的 exception 类
    • 不要返回 null,定义一个 Null 类
    • 不要传递 null
  • Chapter 8  边界

    • 在自己的代码和第三方代码的边界处,使用自己编写的代码适配(适配器),避免将第三方代码直接嵌入自己的代码
    • 测试第三方代码
  • Chapter 9  单元测试

    • TDD
    • 测试代码和生产代码同样重要,但测试代码不一定需要遵循同样的效率和资源限制
    • 保持测试代码的clean,避免过时和冗余等
    • BUILD-OPERATE-CHECK 的测试模板
    • given/when/then 的测试方法命名建议
    • 模板方法模式可能有所帮助
    • 每个测试方法,仅测试一个概念
    • F-I-R-S-T原则
      • Fast,测试效率要高
      • Independent:每个测试应当独立
      • Repeatable:在不同环境下均可运行
      • Self-Validating:应拥有一个boolean的输出,自身直接输出测试是否通过
      • Timely:每个测试应 just before 写在生产代码之前
  • Chapter 10  类

    • 类成员顺序如下,自顶向下

      • public static constants
      • private static constants
      • private instance variables
      • public functions
      • 被 public function  调用的 private functions 紧跟在该 public function 之后,满足自顶向下的阅读顺序
    • 尺寸:类尽可能小,不同于用物理行数衡量方法的尺寸,应该用 responsibilities 衡量类的尺寸。类应保持单一责任。
    • 类应该保持单一责任(SRP),而类名应该描述这一责任。
    • 类名不应超过25个单词,同时避免 if、and、or、but等代表多责任的词,同时少用大范围的含糊的词,如super,manager等。
    • 尽可能提高类的内聚度:尽量使类中的每个成员变量被类方法使用
    • 将大类分隔为很多小类,优化组织性,提高内聚。但也会造成类数量的激增。
    • 依赖倒置原则(DIP),类依赖于抽象,而不是具体实现。降低耦合。
    • 将类中会变化的部分抽象出来,让客户代码依赖于抽象,而不是具体实现。
  • Chapter 11  系统

    • 将系统构造部分,与使用部分解耦
    • 将构造和初始化部分,全部放在main函数中,再在main函数中,将构造完毕的对象,以参数形式传递给具体使用它们的函数。这是一个方法。
    • 工厂方法可能有所帮助。
    • 依赖注入(DI)和控制反转(IoC)机制可能有所帮助。
    • (这一章没怎么看懂)
  • Chapter 12  迭进

    • Kent Beck 认为的“Simple Design”的四条规则。重要性由上而下递减。

      • 运行所有测试
      • 无重复(良好重构)
      • 表现编程者意图
        • 良好命名
        • 保持类和方法尽可能小
        • 遵循公有标准和共同语言,如通用规范、设计模式等
        • 良好的单元测试
      • 最小化类和方法的数量
        • 经过去重、重构等操作之后,类和方法的数量可能激增。因此在此基础上,尽量减少它们的数量。
  • Chapter 13  并发

    • 复杂且不成熟,跳过。
  • Chapter 14  坏味道和启示

    • 注释 Comments

      • C1 不适宜的注释:修改历史、作者、最近修改日志等,都不适宜出现在注释中。注释应该仅保留技术和业务相关的要点。
      • C2 过时的注释
      • C3 冗余的注释:注释是代码的重复,没有提供额外信息
      • C4 写的很烂的注释:认真措辞,不要随意
      • C5 注释起来的代码:没人知道它的重要性和意义,其他人根本无法轻易地改动它。如果可以,直接删除它
    • 环境 Environment

      • E1 构筑环境需要不只一步:做到一键 build 你的项目环境。
      • E2 单元测试需要不只一步:做到一键 test 你的项目的所有单元测试。
    • 方法 Functions

      • F1 太多参数:无参最佳,1参次之,2参再次,3参再次,多余三个参数,则考虑引入参数结构或对象。
      • F2 输出参数:避免改变参数,然后将它作为结果输出。
      • F3 Flag参数:避免使用Flag参数,这意味着这个方法将做不只一件事。
      • F4 Dead方法:无人问津的方法,直接删除它。
    • 通用 General

      • G1 单个源码文件中,出现多种编程语言:解耦、分离他们。
      • G2 明示的行为没有被实现:应该遵循“最低惊异原则”,任何明示而被期待的行为,都应该被正确实现。否则,代码阅读者将会对更多的代码失去信任。
      • G3 边界处的行为都要被准确实现:任何边界条件、角落case、巧合case、异常case的行为,都需要被准确实现。否则,代码阅读者将会对更多的代码失去信任。
      • G4 覆盖安全机制:避免覆盖你使用的框架提供的安全代码机制,如警告等,不要轻易重载、覆盖、取消它们。
      • G5 重复:不仅包括明显重复的代码,还包括重复的设计等。善用模板方法和策略等设计模式。
      • G6 错误/混乱抽象分层:不同抽象层级的隔离应该明确,一个方法应该仅在同一抽象层级上操作。
      • G7 基础类依赖于它们的衍生类:不要让抽象上层依赖于抽象下层,抽象上层应该对抽象下层一无所知。也有例外:比如上层严格控制了下层衍生物的数量等。
      • G8 单个方法/类/模块负责通过多责任:约束尺寸,约束责任,约束信息。
      • G9 Dead Code:避免永远不会执行的代码,直接删除它。
      • G10 垂直分隔:局部变量和方法需要被定义在他们的使用者附近。private function应该被定义在just below他们的首次调用者处。保持自顶向下的阅读顺序。
      • G11 不一致性:相似的行为应该保持相似一直的结构和命名,保持“最低惊异原则”。
      • G12 杂物:无用的变量,无用的方法,无信息的注释,都应该被尽早删除。
      • G13 人为耦合:解耦那些不必要的、不小心造成的耦合关系。
      • G14 位置不当:类中的方法应该尽量只使用此类中的变量和其他方法,如果某方法更多地使用其他类中的变量和方法,那么它可能需要挪动位置了。
      • G15 传递boolean参数:不要将boolean值作为方法参数,这意味着该方法负责不只一件事。
      • G16 含混的意图:代码自身要意图明确。
      • G17 位置不当:一些变量和方法应该正确地放置在它们最被期待的地方。“最低惊异原则”
      • G18 不适当的static:某些方法适合static,有些不适合,正确处理它们。
      • G19 变量意图不明:使用有解释力和变现力的变量,如合适命名等,增强可读性。
      • G20 方法意图不明:使用有变现力的方法名,增强可读性。
      • G21 对算法理解不明
      • G22
      • G23 建议使用多态来代替if/else和switch/case,当后者重复超过1次时,考虑使用多态替换他们。工厂模式可能有所帮助。
      • G24 建议遵循标准惯例
      • G25 建议使用 Named Constants 代替魔数:魔数自身的变现力低,使用具名常量增强表现力。
      • G26 建议当你首次完成系统时,对细节的完成尽可能详细,不要偷懒。
      • G27 良好结构和惯例之间的取舍,前者优先
      • G28 建议封装条件:将if/else和switch/case处的条件式,用独立而良好命名的方法重新表述,使条件处永远只有一行,并且让那个独立的方法的名字,替你解释此处条件是什么。
      • G29 避免否定条件:首先使用肯定条件。
      • G30 方法只做一件事
      • G31 隐藏临时耦合
      • G32 别随意
      • G33 封装边界条件:将边界条件集中、封装,不要让他们散落各处
      • G34 方法只活动在同一层抽象上
      • G35 让配置信息和数据,保持在高层抽象上,不要定义在底层抽象上,通过参数逐层传递它们。
      • G36 避免多级传递:遵守Law of Demeter
    • Java

      • J1 包引入:如果引入了一个package中的超过两个成员,那么直接引入整个包。
      • J2 不要继承常量:不要将常量声明在基类或接口中,然后继承它们。将常量声明在子类中。
      • J3 使用枚举代替一系列常量。
    • 命名 Naming

      • N1 选择有描述力、表现力的名字
      • N2 在命名时体现不同抽象层级
      • N3 如果可能,采用某些标准惯例下的命名
      • N4 明确命名,避免含混用词
      • N5 相关域越大,其命名可以越长
      • N6 避免编码:??
      • N7 不要将方法不会去做的事,体现在其命名上
    • 测试 Tests

      • T1 不充分的测试
      • T2 使用IDE提供的测试覆盖工具
      • T3 不要跳过那么低级的、显而易见的trivial测试
      • T4
      • T5 细心测试边界条件
      • T6 当你发现bug时,正儿八经地测试它
      • T7 测试失败pattern
      • T8
      • T9 测试需要快速

《Clean Code》阅读笔记的更多相关文章

  1. 阅读《RobHess的SIFT源码分析:综述》笔记

    今天总算是机缘巧合的找到了照样一篇纲要性质的文章. 如是能早一些找到就好了.不过“在你认为为时已晚的时候,其实还为时未晚”倒是也能聊以自慰,不过不能经常这样迷惑自己,毕竟我需要开始跑了! 就照着这个大 ...

  2. RobHess的SIFT源码分析:imgfeatures.h和imgfeatures.c文件

    SIFT源码分析系列文章的索引在这里:RobHess的SIFT源码分析:综述 imgfeatures.h中有SIFT特征点结构struct feature的定义,除此之外还有一些特征点的导入导出以及特 ...

  3. RobHess的SIFT源码分析:综述

    最初的目的是想做全景图像拼接,一开始找了OpenCV中自带的全景拼接的样例,用的是Stitcher类,可以很方便的实现全景拼接,而且效果很好,但是不利于做深入研究. 使用OpenCV中自带的Stitc ...

  4. 阅读《RobHess的SIFT源码分析:综述》笔记2

    今天开始磕代码部分. part1: 1. sift特征提取. img1_Feat = cvCloneImage(img1);//复制图1,深拷贝,用来画特征点 img2_Feat = cvCloneI ...

  5. element-ui button组件 radio组件源码分析整理笔记(一)

    Button组件 button.vue <template> <button class="el-button" @click="handleClick ...

  6. element-ui 组件源码分析整理笔记目录

    element-ui button组件 radio组件源码分析整理笔记(一) element-ui switch组件源码分析整理笔记(二) element-ui inputNumber.Card .B ...

  7. element-ui Carousel 走马灯源码分析整理笔记(十一)

    Carousel 走马灯源码分析整理笔记,这篇写的不详细,后面有空补充 main.vue <template> <!--走马灯的最外层包裹div--> <div clas ...

  8. STL源码分析读书笔记--第二章--空间配置器(allocator)

    声明:侯捷先生的STL源码剖析第二章个人感觉讲得蛮乱的,而且跟第三章有关,建议看完第三章再看第二章,网上有人上传了一篇读书笔记,觉得这个读书笔记的内容和编排还不错,我的这篇总结基本就延续了该读书笔记的 ...

  9. element-ui MessageBox组件源码分析整理笔记(十二)

    MessageBox组件源码,有添加部分注释 main.vue <template> <transition name="msgbox-fade"> < ...

  10. element-ui switch组件源码分析整理笔记(二)

    源码如下: <template> <div class="el-switch" :class="{ 'is-disabled': switchDisab ...

随机推荐

  1. ui component 是一个前端 mvc 开发框架

  2. python之进程,线程,协程简单理解

    进程:资源单位,由操作系统控制调度.正在执行的一个程序或者过程,进程之间不共享资源,进程间通讯手段:管道,队列,信号量等.多用于计算密集型场景,如金融计算 线程:是cpu的最小执行单位,由操作系统控制 ...

  3. UML作业第一次:UML用例图绘制

    UML第一次作业 一. 用例图:用例图(usecase diagram)是UML用于描述软件功能的图形.用例图包括用例.参与者及其关系,用例图也可以包括注释和约束.程序员要画时序图啥的用其他的比较麻烦 ...

  4. Xamarin 自定义 ToolbarItem 溢出菜单实现(Popover/Popup) 弹出下拉效果

    使用  Rg.Plugins.Popup 插件 1.  新建 PopupMenu.xaml <?xml version="1.0" encoding="utf-8& ...

  5. 1、写在开头的话——Tinking in Java 绪论之我见

    新兵道歉!版式不懂,技术若有错误,请指正,或发我邮箱1300431700@qq.com 不胜感激! 本文力图通过文章总结的形式,阐述自己的观点,迫使自己思考书中精髓,即使跟技术无关! 正文开始! “上 ...

  6. codeforces-3

    C Game"23" #include<iostream> using namespace std; int main() { long long n,m; long ...

  7. Vue系列之 => webpack的url loader

    安装: npm i url-loader file-loader -D  //url-loader内部依赖file-loader webpack.config.js const path = requ ...

  8. linux软AP--hostapd+dhcpd

    linux软AP--hostapd+dhcpd 2018年05月08日 ⁄ 综合 ⁄ 共 4908字 ⁄ 字号 小 中 大 ⁄ 评论关闭 随着手机.笔记本等无线设备的增多,公司里的家用三个无线路由器已 ...

  9. 高校表白APP-冲刺第二天

    今天进行了第二次会议. 一.任务: 昨日任务完成基本登录注册修改页面布局. 今日任务完成登录界面的基本框架. 明日任务登录修改注册跳转,解决真机运行闪退. 二.遇到的困难: 登录界面按钮布局位置,输入 ...

  10. 遗传算法(Genetic Algorithm, GA)及MATLAB实现

    遗传算法概述: • 遗传算法(Genetic Algorithm,GA)是一种进化算法,其基本原理是仿效生物界中的“物竞天择.适者生存”的演化法则,它最初由美国Michigan大学的J. Hollan ...