第一章 整洁代码
什么叫整洁的代码? 整洁的代码只做一件事,每个函数、类、模块都全神贯注于一事。
童子军军规:让营地比你来时更干净
第二章 有意义的名字
写代码,要降低代码的模糊度
- 防止使用不同之处较小的两个名字
- 不要使用误导性名称
- Info和Data就像a、an、the一样,是意义含混的废话
- 使用读得出来的名称,避免头字母拼接
- 单字母变量(如i、j、k)最多用于计数器,仅此而已,其他情况尽量不要用
- 类名和对象名应该是名词或名词短语(如Account、AdressParser),避免使用动词
- 方法名应该是动词或动词短语
- 只要短语足够清楚,就要比长名称好
第三章 函数
- 函数应该短小
- 每个函数只做一件事
- 函数的缩进层级不应该多余两层
- 长而具有描述性的名称,比短而令人费解的名称好
- 对于一元函数,函数和参数应当形成一种非常良好的动词/名词形式
- 函数要么做什么事,要么回答什么事,但二者不可兼得
- 最好把try catch代码块从主体部分抽离出来,另外形成函数
- 大师级程序员把系统当做故事来讲
第四章 注释
- todo是一种程序员认为应该做,但是由于某种原因目前还没做的工作
第五章 格式
- 向报纸学习,名称应当简单且一目了然
- 紧密相关的代码应该互相靠近
- 若某个函数调用了另一个函数,就应该把它们放到一起,而且调用者应该尽可能放在被调用者上面
第六章 得墨忒定律
- 模块不应了解它所操作对象的内部情况
- 方法不应调用由任何函数返回的对象的方法
第七章 错误处理
- 使用异常而非状态码
- 别返回null值
第八章 边界
- 良好的软件设计,无需巨大投入和重写即可进行修改
第九章 单元测试
-
TDD三定律
- 在编写不能通过的单元测试前,不可编写生产代码
- 只可编写刚好无法通过的单元测试,不能编译也算不通过
- 只可编写刚好足以通过当前失败测试的生产代码
-
保持测试整洁,测试代码和生产代码一样重要
-
每个测试一个断言,每个测试函数只测试一个概念
第十章 类
- 类中出现变量的顺序
- 公共静态变量
- 私有静态变量
- 私有实体变量
- 类的名称应该描述其权责
- 单一权责原则(SRP):每个小类封装一个权责,只有一个修改的原因
- 将大函数拆为许多小函数,往往也是将类拆分为多个小类的时候
第十一章 系统
- “一开始就作对系统”纯属神话。反之,应该只去实现今天的用户故事,然后重构,明天再扩展系统,实现新的用户故事,这就是迭代和增量敏捷的精髓所在。
- 没必要先做大设计,实际上,先做大设计甚至是有害的,它阻碍改进,因为心理上会抵制丢弃即成之事。
- 从简单自然但切分良好的架构开始做软件项目,快速交付可工作的用户故事,随着规模的增长添加更多基础架构。
- 过度工程化而没能有效切分关注面的api,在没能真正得到使用时,设计得再好的api也等于杀鸡用牛刀
- 无论是设计系统或单独的模块,别忘了使用大概可工作的最简单方案
第十二章
- 单元测试消除了对清理代码就会破坏代码的恐惧
- 重复是拥有良好设计系统的天敌
- 模板方法模式是一种移除高层及重复的通用技巧
第十三章
资源定义
- 限定资源:并发环境中有着固定尺寸或数量的资源
- 互斥:每一时刻仅有一个线程能访问共享数据或共享资源
- 线程饥饿:一个或一组线程在很长时间内或永久被禁止
- 死锁:两个或多个线程互相等待执行结束,每个线程都拥有其他线程需要的资源,且得不到其他线程拥有的资源
- 活锁:执行次序一致的线程,每个都想要起步,但发现其他线程已经“在路上”了
第十四章
- 毁坏程序的最好方法之一就是已改进之名大动其结构。采用TDD,就不会允许做出破坏系统的修改,每次修改都得必须保证系统能想以前一样工作
- 优秀的软件设计,大都关乎分隔——--创建合适的空间放置不同种类的代码