代码整洁之道
2019-12-09 10:13:04 2 举报
AI智能生成
代码整洁之道-思维导图
作者其他创作
大纲/内容
代码整洁之道(clean code)
有意义的命名
名副其实
设置可读性高的名称
避免误导
错误缩写简称,例如:hp
别用“字母l”和“字母O”
accountList表示一组账号,应该使用accountGroup合理一些
提防使用细小区别的名称,例如:XyzController和XzzController
做有意义的区分
变量名称,例如错误数字命名:a1、a2、a3
冗余的废话,例如:info、data等
使用读的出来的名称
使用错误的缩写,例如:generationTimeStamp-->genymdhms
使用可以搜索的名称
变量作用域大,应该取便于全文搜索的名称
避免使用编码
使用前缀,例如:m_desc
接口与实现,例如:使用I开头接口名称IShapeFactory
避免思维映射
避免取得名称,翻译成他们熟知的名称
类名
应采用名词或者名词短语
方法名
应采用动词或者动词短语,例如:get、set、is前缀,deletePage、save等
别扮可爱
使用俗语和昵称
每一个概念对应一个词
查询:query、select使用一种风格
controller控制层,不要采用manager或者driver这类不统一风格
别用双关语
例如:add添加还是追加,使用insert或者append更加精准表示
使用解决方案领域名称
例如:AccountVisitor账户访问者、JobQueue工作队列
使用源自所涉及问题领域名称
添加有意义的语境
例如:名字 lastName,fristName
不要添加没用语境
函数
短小
函数方法最佳20行
只做一件事
每个函数方法只做一件事情(单一原则)
每个函数的抽象层级
一件事情抽象层一个方法,遵循自顶向下原则:自下原则
switch语句
应该把这个逻辑抽象到更底层代码中
使用描述性名称
别怕名字太长
别怕取名字花时间
函数参数
一元函数
尽量参数和返回值相同
标识参数
应禁止传入布尔值作为参数,如果有必要可以拆分成两个方法
二元函数
尽量写成一元函数,如果有必要,必须命名清楚名称
三元函数
少些,有足够的理由可以写三元函数
参数对象
多个参数封装成类对象传递
参数列表
如果有可变参数,最好不要超过三元
动词与关键字
命名最好动词加上关键词
无副作用
函数中不能包含隐患作用,输出参数需要修改,尽量使用对象的状态
分割指令与询问
判断值和修改值,必须得分开处理事情,例如:attributeExist(\"user\")和setAttribute(\"a\
使用异常代替返回错误码
抽离try/catch代码
主体代码块中抽离出来
错误处理就是一件事
try/catch/finally后面应该无其他内容
依赖磁铁
例如:消除错误码枚举类,应该使用异常派生类
别重复自己
消除重复代码,抽离公共到底层
注释
注释不能美化糟糕的代码
用代码阐述
好注释
法律信息
提供信息注释
对意图的解释
某个决定的意图
阐述
一些晦涩的词汇
警示
告诉后续维护者存在的分险
TODO注释
用于未完成的任务,但是代码提交后不应该有这样的注释
公共API中的Javadoc
坏注释
喃喃自语
多余注释
误导性注释
具有误导作用的注释
循规式注释
增加不必要规则注释
日志式注释
废话注释
能用函数或者变量的注释
位置注释
例如“////////”
括号后面的注释
注释掉的代码
应该删除,不应该留在代码中
信息过多
过多的注释
非公共API的Javadoc
格式
按IDEA或者Eclipse工具标准格式
对象和数据结构
数据抽象
数据内部细节,应该隐藏细节,统一接口暴露出去
数据、对象的反对称性
过程式的代码难以添加数据结构,必须修改所有函数
面向对象的代码,难于添加新函数,必须修改所有类
迪米特法则
隐藏细节,减少耦合度
数据传输对象DTO
公共变量数据结构,没有函数的类,应用与数据库、通信场景
错误处理
使用异常而非返回码
先写Try/Catch/Finally语句
使用不可控异常
例如:可控异常(checked exception),破坏每个调用层链,底层修改,上层也要跟着修改,破坏封装性
出现异常要详细堆栈信息
要打印出错误,堆栈轨迹信息
依据调用者需要定义异常类
封装第三方异常类
定义常规流程
特列对象:创建一个类、或者配置一个对象,封装到对象中
别返回null值
避免别人出现NPE异常,例如:返回异常或者空对象列表
别传递null值
也容易出现NPE异常
边界
使用第三方代码
浏览与学习边界
学习型测试
保证版本兼容和第三方接口理解
整洁边界
如何保证尽量小,改动原有的类,例如:适配器模式Adapter
使用尚不存在的代码
单元测试
TDD三定律
在编写不能通过单元测试前,不能编写生产代码
只可编写刚好无法通过的单元测试,不能编译也算无法通过
只可编写刚好足以通过当前失败测试的生产代码
编写生产代码前,必须先编写单元测试
保持测试代码整洁
迭代失败的根源
测试代码不整洁,就会出现脏测试,无法覆盖全
测试代码和生产代码一样重要,同时迭代更新
测试能带来一切好处
预知测试缺陷
预知代码结构设计和架构的整洁
整洁的测试
可读性
构造参数
操作测试数据(业务逻辑)
校验数据(例如:断言AssertEquals())
面向特定领域的语言
指的是提供一个API或者第三方包,要提供单元测试,方便他人使用
双重标准
测试代码和生产代码,在不同环境中,测试代码可能达不到生产代码,做的那么简洁,我们不应该强制要求测试代码标准
每个测试一个断言
如果因为分解代码,导致重复代码,应该放在基类
每个测试都只有一个概念
测试多个,应该对代码进行拆分
F.I.R.S.T原则
快速
应该能快速运行
独立
测试应该相互独立,可以独立运行测试
可重复
测试应当应该每个环境都能通过
自足校验
每个校验都应该用布尔值判断,而不是通过日志
及时
生产的代码应该编写测试代码之后
类
类的组织
尽量保证自顶而下的原则,先公共函数,在私有函数
封装性,尽可能不破坏
类应该短小
单一权责原则
应该划分权责,类应该尽量的小,只有一个修改原因
内聚
保持内聚性就会许多短小的类
内聚性必然拆分成更多类
为了修改而组织
隔离修改
依赖倒置:接口或者抽象
适配模式
并发编程
为什么要并发
并发其实是一种解耦策略
迷思与误解
一定能改进性能
并发程序无需设计
采用web或者EJB容器,并发问题不重要
正确说法
增加一些开销
正确的并发是复杂的
并发的缺陷总是很难重现
并发常常设计策略上根本性修改
挑战
JIT编译原理
Java内存模型
并发防御原则
SPR原则:尽可能分离并发代码与其他代码
限制数据作用域
严格限制共享数据的访问作用域
使用数据复本
创建复本,低于增加同步执行开销
线程尽可能的独立
尝试将数据分解到可被独立线程中
了解Java库
线程安全的类库
java.util.concurrent包
了解执行模型
限定资源
生产者-消费者模型
线程饥饿
作者-读者模型
如何避免线程饥饿,平衡作者与读者线程
死锁、活锁、互斥
尽可能减小同步区域
测试线程代码
必须测试线程代码
装置试错代码
硬编码
wait()、sleep()
自动化
通过CGLIB或者ASM
味道与启发
不恰当的信息
废弃的注释
例如:废弃、过时、无关和不正确的注释
冗余的注释
例如:多余注释
糟糕的注释
注释的代码
必须要删除掉,无任何意义的代码
过多参数
输出参数
避免使用输出参数,如果必须修改就修改对象的状态
避免使用布尔值传参
死函数
不被调用函数应该删除
一般性问题
不正确的边界
忽视安全
消除重复
在错误的抽象层上代码
静态变量在基类
基类依赖于派生类
基类不能因基类依赖派生类
接口方法过多
死代码
调用不到的代码必须删除,例如:if/case中代码
前后不一致
使用变量名字应该前后保持一致,便于阅读
不恰当使用静态变量
用多态替代 if/else和Switch/case
用命名常量代替魔法数值
避免否定条件
Java
不要继承常量
Enum代替常量
导入包过多清单,采用通配符,例如:com.ycz.*
名称
采用描述性名称
名称应与抽象层级相符
使用标准命名
使用无歧义名称
避免编码
为作用较大范围的采用较长的名称
测试
别略过测试
测试应该快速
使用覆盖性工具,例如:idea约束条件,提示性错误
0 条评论
回复 删除
下一页