代码整洁之道
2021-09-27 10:24:53 0 举报
AI智能生成
《代码整洁之道》 读书知识归纳
作者其他创作
大纲/内容
规范
整洁代码
集中
整洁的代码只做好一件事
可读性
见名知意
表达力
小规模抽象
易修改
消除重复
命名
名副其实
命名可以不需要注释来补充说明
类和对象用名词
方法用动词
函数使用描述性的名称
别害怕长名称
别害怕花时间取名字
命名方式保持一致
避免混淆
避免系统关键词
避免相似
避免无意义词汇
废话都是冗余
避免添加不必要的语境
易于搜索
避免使用编码
成员前缀
借口和实现
函数
短小
函数不该长于一屏
函数的缩进层次不该多于一层或两层
只做一件事
判断函数是否只做了一件事的方法就是是否能再拆出一个函数
如果是有副作用的函数,应在函数名中说明
例如checkPassword() 中做了Session初始化,应修改为checkPasswordAndlnitializeSession()
每个函数一个抽象层级
向下规则
参数
最理想的参数是零,其次是二,避免三或以上
方便理解
方便测试
事件函数
需要有入参和出参,形成链路
没有返回的参数
标志参数
避免传入boolean类型的参数
分隔指令和询问
错误范例
if(set("username", "licong"))
正确范例
if(attributeExists("username")) {
setAttribute("username", "licong");
}
setAttribute("username", "licong");
}
异常使用
使用异常处理代替返回错误码
当返回错误码时就是要求调用者立马处理错误
抽离try/catch代码块
便于理解和修改
错误处理就是一件事
如果某个函数中存在try关键字,它就应该是第一个单词,而且catch/finally代码块后面也不应该有其他的内容
别重复自己
重复会导致问题
识别困难
代码臃肿,修改困难
消除重复的例子
抽出基类
面向切面编程
面向组件编程
注释
含义
如果编程语言足够有表达力,我们就不需要注释,注释是在我们用代码表达意图失败时的弥补措施
注释存在的时间越久,就离其所描述的代码越远
程序员应当将注释保持在可维护、有关联和精确的高度
我们应该多花心思减少注释量
注释不能美化糟糕的代码
用代码来代替注释进行阐述
好注释
法律信息
提供信息的注释
对意图的解释
警示
TODO注释
定期检测TODO,处理没有暂时没有进行处理的工作
删除不必要的TODO
公共API中的javadoc
坏注释
喃喃自语
如果只是因为你觉得应该或者因为过程需要就添加注释
多余的注释
误导性注释
循规式注释
作者批判每个函数和每个变量都需要注释的规定
日志式注释
废话注释
嘿嘿
产生废话不可怕,可怕的是连废话都是错误的
位置标记
只有在特别有价值的时候采用。当标记栏不多,就会显而易见
归属与署名
现在有版本控制,所以更加没必要写这种注释
注释掉的代码
如果代码不用直接删除掉
非本地信息
该方法并没有对8082端口进行控制,却写在该方法的注释中
信息过多
不明显关系
注释的作用就是解释代码,如果注释还需要注释来进行解释,就不是好注释
格式
应该选用一套管理代码格式的简单规则,然后贯彻这条规则
垂直格式
短文件通常比长文件更容易让人接受
使用空白行将不同的概念分割开
将关系紧密的代码放置在同一源文件中,防止读者在源文件中跳来跳去
变量的声明应尽可能靠近其使用的地方
相关函数
调用者应该尽可能放在被调用者上面
概念相关的一组函数应该放置在一起
横向格式
大约80-120字符一行
代码格式
赋值符号左右添加空格
加强分割效果
乘法之间不用加空格
较高的优先级
加减法之间添加空格
优先级较低
不建议对齐一组声明的变量名
这样会显得强调不重要的东西
缩进
一行代码也要进行缩进
就是是空范围{}也需要进行缩进
每个人都有自己喜欢的格式规则,但是在团队中就以团队为准
对象和数据结构
数据抽象
不要乱加get和set
这是一组表示坐标的数据,将x和y的赋值作为一组原子性的操作
不暴露细节,以抽象形式表述数据
过程式代码便于添加新的函数
面向对象代码便于添加新类
德墨忒耳律
模块不应该了解它所操作对象的内部情形
链式编程是否违反了该定律?
直接ctxt.getAbsoulutePath()如何?
数据传送对象
DTO(Data Transfer Objects)
只有公共变量,没有函数
系统
错误处理(异常处理)
异常处理是程序必须做的事情之一,但是如果因为它搞乱了代码逻辑
让读者无法看明白代码所做的事情,就是错误的做法
让读者无法看明白代码所做的事情,就是错误的做法
使用异常而非错误码
该代码是单条件,不满足条件无程序执行,才适用于书中所说的修改方案
整理后的
打包异常
当需要捕获多个第三方API的异常并进行不同的逻辑操作时,可以将处理异常的过程新建一个打包类,
不仅代码更简洁,而且减少了对它的依赖
不仅代码更简洁,而且减少了对它的依赖
特例模式
创建一个类或配置一个对象,用来代替处理个别异常的行为。业务代码就不用进行异常处理了
别返回null
用空的集合返回,减少多做空值检查判断
水哥的selectList()查询采用了该方式
别传递null值
边界
关于使用第三放库的建议,暂时不太理解
单元测试
测试驱动开发
TDD三定律(待定)
在编写不同通过的单元测试前,不可编写生产代码
只可编写刚好无法通过的单元测试,不能编译也算不通过
只可编写刚好足以通过当前失败测试的生产代码
测试代码和生产代码一样重要
好的全套自动化单元测试可以确保修改生产代码后的程序正确性
单元测试让你的代码可拓展、可维护、可复用
减少对修改代码的担忧,测试覆盖率越高,就越不担心修改
整洁的测试
可读性
明确、简洁、有足够的表达力
每个测试一个概念、一个断言
规则FIRST
快速Fast
独立Independent
可重复Repeatable
自足验证Self-Validating
及时Timely
测试与生产的双重标准
例如字符串的拼接在测试中可以直接用+,而不用StringBuilder或StringBuffer,因为不用担心内存资源问题
类
类应该从一组变量列表开始,如果有公共静态常量,应该先出现,然后是私有静态变量,以及私有实体变量
类应该短小
类的名称应当描述其职责
类名越含糊,则说明该类的职责过多
单一权责原则SRP
开放闭合原则OCP
类应当对拓展开放,对修改关闭
依赖倒置原则DIP
类应当依赖于抽象而不是依赖于具体细节
内聚
内聚性高,意味着类中的方法和变量相互依赖、互相结合成一个逻辑整体
系统
将系统的构造与使用分开
抽象工厂模式让应用自行控制何时创建对象,将构造的细节与应用程序代码隔离
依赖注入DI
控制反转IoC
测试驱动系统架构
由模块化的关注面领域组成
使用单一语言对象实现
不同领域之间不具侵害性
侵害性架构会湮灭领域逻辑,冲击敏捷能力
导致缺陷隐藏,生产力下降
导致缺陷隐藏,生产力下降
迭进
运行所有测试
系统的修改必须可测试、可验证
不可重复
额外的工作
额外的风险
额外的复杂度
表达了程序员的意图
多花时间去尝试、去调整
尽可能减少类和方法的数量
应当避免教条式的去遵循规定,比它更重要的是测试、消除重复和表达力
并发编程
并发是一种解耦策略,将目的和时机分解开,能明显的改进应用程序的吞吐量和结构
对于并发的一些说法
并发会在性能和编写额外代码上增加一些开销
正确的并发是复杂的,即便对于简单的问题也是如此
并发缺陷并非总能重现,所以常被看做偶然事件而忽略,未被当作真的缺陷看待
并发常常需要对设计策略的根本性修改
并发防御原则
单一责权原则SRP
分离并发相关代码与其他代码
限制数据作用域
无法预期的行为采用synchronized保护使用共享对象的临界区
使用数据复本
从多个线程收集所有复本的结果,并在单个线程中合并这些结果
线程应尽可能独立
java.util.concurrent包
执行模型
基础定义
限定资源
并发环境中有着固定尺寸或数量的资源。
例如数据库连接和固定尺寸读写等
例如数据库连接和固定尺寸读写等
互斥
每一时刻仅有一个线程能访问共享数据或共享资源
线程饥饿
一个或一组线程在很长时间内或永久被禁止。
例如:总是让执行得快的线程先运行,假如执行得快的线程没完没了,则执行时间长的线程就会“饥饿”
例如:总是让执行得快的线程先运行,假如执行得快的线程没完没了,则执行时间长的线程就会“饥饿”
死锁
两个或多个线程互相等待执行结束。每个线程都拥有
其他线程需要的资源,得不到其他线程拥有的资源,就无法终止
其他线程需要的资源,得不到其他线程拥有的资源,就无法终止
活锁
执行次序一直的线程,每个都想要起步,但发现其他线程已经在路上。
由于竞步的原因,线程会持续尝试起步,但在长时间内却无法如愿,甚至永远无法启动
由于竞步的原因,线程会持续尝试起步,但在长时间内却无法如愿,甚至永远无法启动
生产者-消费者模型
一个或多个生产者线程创建某些工作,并置于缓存或队列中
一个或多个消费者线程从队列中获取并完成这些工作
生产者和消费者之间的队列是一种限定资源
读者-作者模型
一个共享资源,主要为读者线程提供信息源,偶尔被作者线程更新
宴席哲学家
应对并发
避免使用一个共享对象的多个方法,如果必须则
基于客户端锁定
客户端在调用第一个方法前锁定服务器
基于服务端锁定
服务端内创建锁定服务端的方法,并调用所有方法
适配服务端
创建执行锁定的中间层
保持同步区域微小
尽早考虑线程关闭问题
测试线程代码
测试并不能确保正确性,但是能尽量降低风险
将偶发事件看作可能的线程问题
确保非线程代码可正常工作
编写可插拔的线程代码
编写可调整的线程代码
运行多于处理器数量的线程
在不同平台上运行
装置试错代码
硬编码
增加wait、sleep、yield等方法调用,改变代码执行顺序
自动化
Aspect-Oriented Framework
CGLIB
ASM
小结
本书从14章之前是对于整洁代码的思路与策略,以不重复原则为核心,衍生大量的规范编程。
从14章开始作者用大量的代码进行示例逐步改造的过程,包含测试用例以及一些类库的重构。满满的干货,可以遵循着作者的代码将前面提出的概念很好的过一遍
第17章为作者整理出清单式的建议,满满的干货,看这本书,完全可以先把第17章的内容精读一遍,立马可以运用到工作之中
从14章开始作者用大量的代码进行示例逐步改造的过程,包含测试用例以及一些类库的重构。满满的干货,可以遵循着作者的代码将前面提出的概念很好的过一遍
第17章为作者整理出清单式的建议,满满的干货,看这本书,完全可以先把第17章的内容精读一遍,立马可以运用到工作之中
0 条评论
下一页