• 一、参考资料
  • 二、重构步骤 - 以提炼重复计算函数为例子
    • 演示代码
    • 具体步骤
      • 1.提取重复new创建
      • 2.提取会变化的信息
      • 3.使用抽取的共有信息,并删除原有信息
      • 4.提取计算函数
      • 5.使用卫语句,简化代码逻辑

一、参考资料

  1. 《重构 2》6.1 提炼函数
  2. 《重构 2》10.3 以卫语句取代嵌套条件表达式

二、重构步骤 - 以提炼重复计算函数为例子

演示代码

如下代码,存在坏味道

  1. 充斥着if else
  2. 重复的new Length()创建
  3. 重复的参数this.value 和 target_unit
    唯一的不同点 仅仅是计算的方式 如 value / 3,value * 12
public Length as(Unit target_unit) {Length result = this;if (this.unit == Unit.FOOT) {if (target_unit == Unit.YARD) {result = new Length(this.value / 3, target_unit);} else if (target_unit == Unit.INCH) {result = new Length(this.value * 12, target_unit);}}if (this.unit == Unit.YARD) {if (target_unit == Unit.INCH) {result = new Length(this.value * 36, target_unit);} else if (target_unit == Unit.FOOT){result = new Length(this.value * 3, target_unit);}}return result;
}

具体步骤

注:以下只展示最关键的代码降低认知负载,做了变化的地方,在代码上都会注释

1.提取重复new创建

例如:下面代码中new Length()为重复创建

public Length as(Unit target) {// 提取了重复的new创建Length result = new Length(this.value, target);if (this.unit == Unit.FOOT) {if (target == Unit.YARD) {// 提取了重复的new创建result = new Length(this.value /3, target);} else if (target == Unit.INCH) {// 提取了重复的new创建result = new Length(this.value * 12, target);}}//省略...,其他代码同理
}return result;
}

2.提取会变化的信息

例如:下面代码中this.value是会变化的

public Length as(Unit  target) {// 提取会变化的信息double value = this.value;Length result = new Length(value, target);if (this.unit == Unit.FOOT) {if (target == Unit.YARD) {// 提取会变化的信息value = value / 3;result = new Length(value, target);} else if (target == Unit.INCH) {// 提取会变化的信息value = value * 12;result = new Length(value, target);}}//省略...,其他代码同理return result;
}

3.使用抽取的共有信息,并删除原有信息

例如:下面代码中,共有信息new Length() 和 value,因为使用了共有信息,此时原有信息result就没用了
注:当没用引用时,result变量名会变灰,此时可以用 alt + enter,会有个安全删除,选择安全删除,则会吧所有的result都同步删掉

public Length as(Unit target) {double value = this.value;if (this.unit == Unit.FOOT) {if (target == Unit.YARD) {value = value / 3;} else if (target == Unit.INCH) {value = value * 12;}}// 使用抽取出来的信息return new Length(value, target);
}

4.提取计算函数

  1. 例如:下面代码,吧获取value的信息,抽取为方法,封装具体实现,这样当阅读这段代码时,不需要了解具体实现,通过方法名就可以知道这是做什么,相比之前,需要去看这段代码是干什么的,可读性更高。
  2. 建议:在代码中,可以采取抽取方法的方式,对代码的结构进行一个划分,使其可读性更好
  3. 抽取方法快捷键参考
    后继会出文章,讲解,抽取为方法的好处,以及实战
public Length as(Unit target) {// 提炼函数double value = getValue(target);return new Length(value, target);
}
// 提炼函数
private double getValue(Unit target) {...
}

5.使用卫语句,简化代码逻辑

public Length getValue(Unit target) {if (this.unit == Unit.FOOT) {if (target == Unit.YARD) {//  提前返回,消除elsereturn this.value / 3;}if (target == Unit.INCH) {//  提前返回,消除elsereturn this.value * 12;}}//省略...return this.value;
}

重构 - 提炼函数,消除重复代码相关推荐

  1. 无码系列5.1 代码重构 消除重复代码

    1 前言 本文可以视为对ThoughtWorks高级顾问yuanyingjie关于"正交四原则"策略"消除重复"的"个人解读". 如有谬误, ...

  2. 利用注解 + 反射消除重复代码(Java项目)

    作者 | Leilei Chen 来源 | https://llchen60.com/ 1. 案例场景 假设银行提供了一些 API 接口,对参数的序列化有点特殊,不使用 JSON,而是需要我们把参数依 ...

  3. 利用注解 + 反射消除重复代码,妙!

    1.1 案例场景 假设银行提供了一些 API 接口,对参数的序列化有点特殊,不使用 JSON,而是需要我们把参数依次拼在一起构成一个大字符串: 1)按照银行提供的API文档顺序,将所有的参数构成定长的 ...

  4. java 重复代码优化_利用注解 + 反射消除重复代码(Java项目)

    1. 案例分析 1.1 案例场景 假设银行提供了一些 API 接口,对参数的序列化有点特殊,不使用 JSON,而是需要我们把参数依次拼在一起构成一个大字符串 按照银行提供的API文档顺序,将所有的参数 ...

  5. 【译】利用Lombok消除重复代码

    当你在写Getter和Setter时,一定无数次的想过,为什么会有POJO这么烂的东西.你不是一个人!(不是骂人-)无数的开发人员花费了大量的时间来写这种样板代码,而他们本来可以利用这些时间做出更有价 ...

  6. oracle消除重复的行使用的什么函数,利用Oracle的row_number() over函数消除重复的记录...

    2.select d.id,d.outer_code,row_number() over(partition by outer_code order by outer_code) row_flag f ...

  7. 【重构】 代码的坏味道总结 Bad Smell (一) (重复代码 | 过长函数 | 过大的类 | 过长参数列 | 发散式变化 | 霰弹式修改)

    膜拜下 Martin Fowler 大神 , 开始学习 圣经 重构-改善既有代码设计 . 代码的坏味道就意味着需要重构, 对代码的坏味道了然于心是重构的比要前提; . 作者 : 万境绝尘 转载请注明出 ...

  8. 《重构:改善既有代码的设计》读书笔记(上)

    第一章:重构第一个示例   第一章作者通过一个示例讲解重构的过程.由于需求变化或代码不易于理解需要进行重构,重构前需要有一个可靠的测试,重构的过程应该是小步修改,每次修改后就运行测试,测试过程中可以先 ...

  9. 读《重构:改善既有代码的设计》的思考

    大家好,你们的简单猿来了. 今天我们聊一下<重构:改善既有代码的设计>这本书.以下简称为 "重构". 1.什么是重构? 按本书中的说法,重构这个概念被分成了动词和名词的 ...

最新文章

  1. OpenSSH升级安装步骤(redhat)
  2. Mass对象类型介绍
  3. SQL   PL/SQL   SQL*PLUS三者的区别
  4. solaris 10 安装Apache Mysql PHP
  5. 深度学习导论(2)深度学习案例:回归问题
  6. rman备份恢复命令之switch
  7. 大数据之HDFS应用开发(java API)
  8. java mapper.readtree_java - 杰克逊的readValue和readTree:何时使用哪个? - 堆栈内存溢出...
  9. 计算机专业英语常用词汇
  10. SpringCloud Consul Config 配置中心 (二)
  11. 机器学习模型的理解(三)
  12. aode matlab程序,三大计算机视觉和机器学习库的算法汇总
  13. java题库app有什么,Java面试题库
  14. arduino编码器计数_【Arduino】旋转编码器的Arduino使用方法
  15. word转换html 批量,Word批量转HTML工具
  16. K近邻算法与K均值算法的区别
  17. 数据结构1800试题(第2章)
  18. 程序员需要的日常(收费)软件(都免费)
  19. 【读书笔记】《结构思考力》——李忠秋
  20. 降噪算法如何评定效果?用标准的方法,科学合理的判定你的降噪算法效果。

热门文章

  1. led灯什么牌子的质量好?能够护眼的LED台灯推荐
  2. linux sda sda1区别,linux – / dev / sda和/ dev / sda1之间的区别
  3. 2020年9月程序员工资最新统计
  4. linux内核形式化验证,聪明人的笨功夫 -- MesaTEE安全形式化验证实践
  5. 4、MyBatis + Log4j日志查看Sql参数、结果集元数据、Mapper代理开发、JDK的动态代理与CGLib代理
  6. Vue3 使用expose让父组件直接修改子组件的值
  7. android桌面布局保存在哪里,android-DatePickerDialog保存屏幕上的布局旋转
  8. Data Whale第20期组队学习 Pandas学习—第一次综合练习
  9. 现代永磁同步电机控制原理及matlab仿真_永磁同步电机是什么?
  10. SpringBoot启动报错Consider defining a bean of type ‘com.test.springmvc.dao.xx‘ in your configuration.