什么情况下应该重构

  • 重复代码(Duplicated code),事不过三,三则重构
  • 过长函数(Long method)
  • 过大的类(Large class)
  • 过长参数列表(Long parameter list)
  • 发散式变化(divergent change),意思是需要加一个新功能或者修改一个己有功能要改多个函数,那么就意味着要重构了。
  • 散弹式修改(shotgun surgery),意思是需要加一个新功能或者修改一个己有功能要改多个类,那么就意味着要重构了。
  • 依恋情节(feature envy),意思是函数对某个类的兴趣高于对自己所处类的兴趣,那么就需要挪个位置了。
  • 数据泥团(data clumps),多个地方定义了相关的字段和参数,我们需要把它提取到一个独立的对象中。
  • 基本类型偏执(primitive obsession),如果有多个关系密切的基本数据类型应考虑组织成有意义的形式。
  • 过多的switch case(switch statements) 尽量不要用switch case,考虑用多态来替代它。
  • 平行继承体系(parallel inheritance hierarchies)每当为某个类添加一个子类,也必须为另一个添加一个子类。策略是让一个继承体系的实例引用另一个继承体系的实例。
  • 冗余类(lazy class) 如果某个类存在没有价值,那么它就应该删除。
  • 夸夸奇谈未来性(speculative generality)程序是迭代的过程,不要想着能一开始设计出一个完美的结构。
  • 令人迷惑的暂时字段(temporary field)可以考虑为可怜的孤儿创造一个家,然后把所有和这个变量相关的代码都放进这个新家。
  • 过度耦合的消息链(message chains)一个对象请求另一个对象,对象再请求对象。考虑是否可以不链接调用完成相关功能。
  • 中间人(middle man)过度委托会增加代码的复杂度,应该考虑消除中间人。
  • 狎昵关系(inappropriate intimacy) 过份狎昵的类必须拆散,同必须严守清规。
  • 异曲同工的类(alternative classes with different interfaces) 如果两个函数做同样的事却有着不同的签名。考虑合并。
  • 不完美的类库(incomplete library class),如果类库满足不了需求。那就添加一个新的方法来处理。
  • 纯稚的数据类(data class) 拥有一些字段用于读写(java bean或者说实体类),应将他们封装起来,变量私有化。
  • 被拒绝的遗赠(refused bequest)子类应该继承父类的数据和方法,但是子类却不想要这些方法或数据。建议超类都是抽象的。
  • 过多的注释(comments)如果代码中有长长的注释,往往是代码特别糟糕。当代码足够清晰,注释就已经变的多余。

重构方法

  • 提炼函数(Extract Method):将独立的功能提炼成一个函数,并通过函数名解释该函数的用途。
  • 内联函数(Inline method): 在函数调用点插入函数本体,然后移除该函数。为了应对 过度封装。
  • 内联临时变量(inline temp) : 将所有对该变量的引用动作替换为对它赋值的那个表达式本身。
  • 以查询取代临时变量(replace temp with query): 将表达式提炼到独立函数为新函数的调用,将临时变量的所有引用点替换为对函数的调用。
  • 引入解释型变量(introduce explaining variable): 将该复杂表达式的结果放入一个临时变量。
  • 分解临时变量(split temporary variable): 针对每次赋值创造一直独立对应的临时变量。不要定义一个临时变量在不同的地方进行多次赋值操作
  • 移除对参数的赋值(remove assignments to parameters): 以一个临时变量取代该函数的位置,不要直接对参数赋值。
  • 替换算法(substitute algorithm) 将函数本体替换成另一个算法。 如果某个算法特别复杂而有更简单的方式,则考虑替换。
  • 搬移函数(move method):当一个类特别臃肿时。在该函数最常引用的类中建立一个有着类似行为的新函数,将旧函数变成一个单纯的委托函数或者直接删除。
  • 搬移字段(move filed) 在目标类新建一个字段,修改源字段的所有用户,令他们改用新字段。
  • 提炼类(extract class) 建立一个新类,将相关的字段和函数从旧类中搬移到新类。
  • 将类内联化(inline class) 如果一个类存在的理由不充分,则考虑将这个类的所有内容移到新类中,然后将原类删除。
  • 隐藏委托管理(hide delegate) 在服务类上建立客户所需的所有函数,用以隐藏委托关系。
  • 移除中间人(remove middle man) 让客户端直接调用受托方。
  • 引用外加函数(introduce foreign method) 在客户端为新建一个函数,并以第一参数形式全心入一个服务端实例。
  • 引入本地扩展(introduce local extension) 建立一个新类,使它包含这些额外函数,让这个扩展品成为源类的子类或包装类。
  • 自封装字段(self encapsulate field): 为这个字段建立取值/设值函数,并且只能以这些函数来访问字段。
  • 以对象取代数据值(replace data value with object) 将一个数据项变成对象。开发初期可能只是一个字段,随着功能的增加字段会越来越多越多。
  • 将值对象改为引用对象(change value to reference) 将这个值变成引用对象。
  • 将引用对象改为值对象(change reference to value) 将它变成一个值对象。
  • 以对象取代数组replace array with object)
  • 以数据类取代记录(replace record with data class) 为记录创建一个哑数据对象。
  • 以类取代类型码(replace type code with class) 以一个新的类替代该 类型码。
  • 分解表达式
  • 合并条件表达式
  • 合并重复的条件判断
  • 移除控制标记
  • 以卫句取代嵌套条件表达式,把条件反转
  • 以多态取态条件表达式或switch
  • 引用null对象,以空对象取代null。当一个字段为Null时,多态就判断不出来该调用哪些方法来做对应的处理。
  • 当函数名不能表达用途的时候,我们需要rename这个函数名。
  • 添加参数/移除参数
  • 将查询函数和修改函数分离
  • 让函数携带参数
  • 以明确函数取代参数, 写两个函数分别调用取代参数判断该调用哪个。
  • 如果一个函数没有被外部调用,则改为private
  • 以工厂函数取代构造函数。
  • 将转型封装在函数中
  • 以异常取代错误码,以测试取代异常
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值