构建测试体系是重构的第一步
小步提交ctrl+k,提交前测试
神秘命名
shift+f6 修改文件和变量名
类、枚举:名词或名词短语
接口:名词名词短语
测试类:名词Test
抽象类:以Abstract或Base开头
方法名:
get+非布尔属性名
is/has/can/should+布尔属性名
set+属性名
has+名词/形容词
动词
动词+宾语
重复代码
重复代码:
ctrl +shift+f10 执行光标用例
选中重复代码,ctrl+alt+M 函数提权重复代码,按一次快捷改名字,两次,可以改其他的东西
shift+10运行上次执行过的用例
子类间重复代码:
ctrl + shift + alt + t然后选择pull member up,函数上移
修改其他子类函数为super.xxx,shift+f10确定用例成功,然后删除子类代码
不同类间的重复代码:
ctrl+shift+上下 移动语句,将相似的代码放在一起
ctrl + shift + alt + t然后选择extract delegate
然后ctrl +shift+f10 ,修改其他重复代码,注释重复部分,调用抽取的方法,然后shift+f10,然后删除代码。
识别工具:analyze
过长函数
过多逻辑功能
过多细节
用做什么命名函数
理解函数意图,归纳功能,功能分割
过多临时变量:用查询代替,光标放在要消除的变量名上,ctrl+alt+N ,
复杂的if,抽象为函数
方法移动:光标放到方法名上,f6(ctrl + shift + alt + t然后选择convert to instance method)
swtich 语句过于复杂,抽取函数
过长参数列表
ctrl+shift+t 类和测试类之间切换
查询取代参数,参数变灰,alt+delete
保持对象完整,多个参数来自一个对象,光标放到调用处,alt+f6,增加对象参数,
引入参数对象,光标放到任意参数上,然后ctrl + shift + alt + t选择introduce parameter obj,然后选择要提取的参数,
移动函数至合适的类,如果用到的参数都是一个类的,先ctrl+alt+M,然后内联ctrl+alt+N,然后f6移动方法
移除标记参数,针对标记参数对应的不同逻辑拆分方法,
if优化为三目运算符,光标放到if上alt+enter
全局数据
封装访问逻辑,移动到对应类里,改为私有变量alter+enter
ctrl+alt+f 替换删除
可变数据
同一变量用作不同目的:职责不单一的变量从拆分
用public修饰非final变量:ctrl + shift + alt + t选择encapsulate field,封装字段
有set方法,builder模式创建不可变对象
一个字段的值可以通过其他字段计算得到,删除冗余计算,
对外暴露内部字段的可变引用, Collections.unmodifiableList(lines);
ctrl+alt+L 格式化
alt + enter remove redundant initializer
构造函数,ctrl+alt+p 将某个变量放到参数列表里
发散式变化
不同原因,不同地方的变化:逻辑杂糅,多个上下文变化,同时引起一个模块的改动
函数内部先将功能相似的语句集中在一起:ctr+alt+上下
拆分阶段
放到for上alt+enter 选择replace with sum,用stream取代for
参数为密切属性,考虑抽象为类
ctrl+k提交变更
ctrl+alt+f 变为成员属性
ctrl + shift + alt + t选择选择convert to instance method转换为实例方法
ctrl+alt+P将某个变量提取为入参
ctrl + shift + alt + t选择选择 extract interface将实例方法,抽象为接口
ctrl+alt+v提炼业务
霰弹式修改
某种变化导致多处改动
搬移字段:f6,alter+enter change access modifier
ctrl+k小步提交
搬移函数,聚合逻辑,抽取方法,看此方法是否跟这个类匹配,不匹配搬移
拆分函数:处理两件事情,可拆分函数
内联函数
常量抽取:ctrl+alt+c
函数组合变换先做拷贝
依恋情节
调用方和被调用方互相知道过多细节:策略、访问者模式往往有依恋情节
依恋特性:变成方法调用,提炼函数,搬移函数
ctrl+w选中代码块
alter+enter create test
数据泥团
成块出现的相同数据项
提炼类:将相同属性的变量放到一个类里ctrl+alter+shift+t,然后选extract delegate,然后参数对象化,ctrl+alter+shift+t选introduce parameter obj,也可以反着
引入参数对象,ctrl+alt+v提取变量,ctrl+alt+f变量变为成员变量,ctrl+alt+p抽取参数
保持对象完整性
setting->editor->inspections看java code style issuses
alter+insert ->constructor
基本类型偏执
a>0 ,a < 10 范围
type=a, type=b ,字符串代替类型
暴露较多细节
ctrl+alter+shift+t选introduce parameter obj,alt+u(选项首字母using existing class)
tab跳转到下一个输入框,勾选框
空格,勾选,取消勾选
针对不同的type创建不同的类,可以考虑抽象工厂方法
重复的switch
影响可维护性
多态取代重复switch
针对当前类名alter+enter create subclass
ctrl+alter+shift+t选replace constructor with factory method
移动方法到子类ctrl+alter+shift+t选push member down, keep abstract
访问权限有问题:放到问题点上,alter+enter -> make xxx public
ctrl+shift+上下,ctrl+w选中代码块
循环语句
stream 替代for
冗赘的元素
安全删除
ctrl+y整行删除
未使用函数、变量使用ctr+del删除
内联
类功能过于单一,没有体现价值,折叠继承,内联,ctrl+alt+n
夸夸其谈的通用性
删除过度设计,
折叠继承:删除不必要的接口和抽象类,很多情况只有一个实现,不暴露实现,
内联类
内联函数
改变函数声明
移除死代码
临时变量
某实例变量仅为一小部分功能临时使用而创建
ctrl+alter+shift+t选remove middleman移除中间人
提取类,封装变量
引入特例,
过长消息链
调用链,消息连
紧耦合
隐藏委托关系
移动方法:先变成静态,然后f6,然后再变成实例方法
深模块:对外接口,小而简单,内部实现复杂
浅模块
中间人
过度使用委托
当需求发生变化,中间人也老是修改,霰弹式修改
移除中间人
内联:只返回属性,ctrl+alt+n
继承取代委托
委托取代超类
ctrl+alter+shift+t -> remove middleman
内幕交易
模块间互相引用
搬移函数、字段,
隐藏委托关系
以委托取代子类
依赖矩阵图:analyze-analyze dependency matrix scope,正常应为左下角,右上角有就为反向依赖
过大的类
职责不单一,包含过多属性、方法和代码行
异曲同工的类
功能相似,却有不同的定义,
修改函数名,
搬移函数,
添加参数,
函数参数化,
提炼超类,
移除子类
纯稚的数据类
dto模型,不提供能力
只有字段,没有逻辑
封装变量
封装集合
搬移函数
抽取方法
移除设值函数
被拒绝的遗赠
某个子类只想继承一部分,可能意味着这种方法并不是子类共有的,
通过函数下移,
以委托取代超类,