重构

 

构建测试体系是重构的第一步

小步提交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模型,不提供能力

只有字段,没有逻辑

封装变量

封装集合

搬移函数

抽取方法

移除设值函数

放到根目录上ctr+shift+f10执行全部用例

被拒绝的遗赠

某个子类只想继承一部分,可能意味着这种方法并不是子类共有的,

通过函数下移,

以委托取代超类,

是否修改需要权衡

posted @ 2022-03-15 21:14  wqkant  阅读(177)  评论(0编辑  收藏  举报