《重构:改善既有代码的设计》-学习笔记二(+实战解析)

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

本人比较直接,不说虚的,直接上干货。

目录

Long Parameter List(过长参数列)

Divergent Change(发散式变化)

Shotgun Surgery(散弹式修改)

Feature Envy(依恋情结)

Data Clumps(数据泥团)

Primitive Obsession(基本型别偏执)

Switch Statements(switch惊悚现身)

Long Parameter List(过长参数列)

==============================

上一节有提过,当函数的入参过多时,可以用第三招,参数对象化,把参数封装成对象,然后参数对象当成函数的入参,达到减少参数的作用。

除了参数对象化,还可以使用另一种方法来处理。

这种方法叫做:Replace Parameter with Method(以函数取代参数)

优化思路


前提,这个参数是只被赋值一次的

1、如果有必要,将参数的计算过程提炼到一个独立函数中。

2、将函数内有使用参数的地方替换成独立函数。

3、每次替换后,测试。

4、全部替换完成后,最后把这个参数删除。

eg:未优化的代码

public double getPrice() {

int basePrice = _quantity * _itemPrice;

int discountLevel;

if (_quantity > 100) discountLevel = 2;

else discountLevel = 1;

double finalPrice = discountedPrice (basePrice, discountLevel);

return finalPrice;

}

private double discountedPrice (int basePrice, int discountLevel) {

if (discountLevel == 2) return basePrice * 0.1;

else return basePrice * 0.05;

}

优化 1,2,3步骤 优化参数basePrice

public double getPrice() {

int basePrice = getBasePrice();

int discountLevel;

if (_quantity > 100) discountLevel = 2;

else discountLevel = 1;

double finalPrice = discountedPrice ( discountLevel);

return finalPrice;

}

private double discountedPrice ( int discountLevel) {

if (discountLevel == 2) return getBasePrice() * 0.1;

else return getBasePrice() * 0.05;

}

private int getBasePrice(){

return _quantity * _itemPrice;

}

优化4步骤 去掉参数basePrice

public double getPrice() {

int discountLevel;

if (_quantity > 100) discountLevel = 2;

else discountLevel = 1;

double finalPrice = discountedPrice ( discountLevel);

return finalPrice;

}

private double discountedPrice ( int discountLevel) {

if (discountLevel == 2) return getBasePrice() * 0.1;

else return getBasePrice() * 0.05;

}

private int getBasePrice(){

return _quantity * _itemPrice;

}

优化1,2,3,4步骤,去掉discountLevel参数,独立函数返回值要为discountLevel 最后赋值的值

public double getPrice() {

double finalPrice = discountedPrice ();

return finalPrice;

}

private double discountedPrice () {

if (getDiscountLevel() == 2) return getBasePrice() * 0.1;

else return getBasePrice() * 0.05;

}

private double getDiscountLevel(){

if (_quantity > 100) return 2;

else return 1;

}

private double getBasePrice(){

return _quantity * _itemPrice;

}

从上述代码可看出,getPrice主函数finalPrice参数已经可以直接优化了。

public double getPrice() {

return discountedPrice ();

}

可以发现getPrice函数直接调用discountedPrice 函数,所以可用Inline Method(将函数内联化)

合并这两个函数

public double getPrice() {

if (getDiscountLevel() == 2) return getBasePrice() * 0.1;

else return getBasePrice() * 0.05;

}

private double getDiscountLevel(){

if (_quantity > 100) return 2;

else return 1;

}

private double getBasePrice(){

return _quantity * _itemPrice;

}

我们只关心主函数的计算过程,一些过程性的计算,像上述这样,独立函数出来。代码逻辑会十分清晰,可读性很好。

存在一个重要的例外。如果明显不希望封装的对象与主对象之间存在某种依赖关系,可以把参数数据从封装对象中抽出来,当成函数的参数。也是合理的。

但是要注意,当参数列太多或者参数变化频繁时,就要考虑优化了。

Divergent Change(发散式变化)

===========================

你发现你想要修改的一个函数,却必须同时修改诸多不相关的函数,例如,当你想要添加一个新的产品类型,你需要同步修改对产品查找,显示,排序的函数。

有以上这些情况的话,就需要优化代码了

针对某一外界 变化的所有相应修改,都只应该发生在单一class中,而这个新class内的所有内容都应该反应该外界变化。

通过提炼类的方式,找出因着某特定原因而造成的所有变化,独立类。

问题原因:

通常,这种发散式修改是由于编程结构不合理或者“复制-粘贴式编程”。

优化思路


运用提炼类拆分类的行为。

如果不同的类有相同的行为,你可以考虑通过继承来合并类和提炼子类。

效果:

提高代码组织结构

减少重复代码

Shotgun Surgery(散弹式修改)

==========================

注意霰弹式修改 与 发散式变化 区别 : 发散式变化是在一个类受多种变化影响, 每种变化修改的方法不同, 霰弹式修改是 一种变化引发修改多个类中的代码;****

优化思路


1、代码集中到某个类中 : 使用 Move Method(搬移函数) 和 Move Field(搬移字段) 把所有需要修改的代码放进同一个类中;

2、 代码集中到新创建类中 : 没有合适类存放代码, 创建一个类, 使用 Inline Class(内联化类) 方法将一系列的行为放在同一个类中;

3、造成分散式变化 : 上面的两种操作会造成 Divergent Change(分散式变化), 使用Extract Class 处理分散式变化;

Feature Envy(依恋情结)

======================

函数对某个class的兴趣高过对自己所处之 class的兴趣。无数次经验里,我们看到某个函数 为了计算某值,从另一个对象那儿调用几乎半打的取值函数。

影响:数据和行为不在一处,修改不可控。

解决方案:让数据和行为在一起,通过 Extract Method(提炼函数)和Move Method(搬移函数)的方法来处理,这函数到该去的地方。

例子:参考一个优秀博主提供的例子

https://blog.youkuaiyun.com/wxr0323/article/details/7884168

优化思路


1、函数全部数据来自另外一个类

做法:将数据提炼到一个独立函数中  Move method。

2、函数部分数据来自另外一个类

做法:将“部分数据”提炼到一个函数中 Move method。

3、函数的数据来自不同类

做法:将数据分类,分别提炼各自的独立的函数,在将这些函数移到各自属于的类中。

Data Clumps(数据泥团)

=====================

数据泥团指的是经常一起出现的数据,比如每个方法的参数几乎相同,处理方式与过长参数列的处理方式相同,用_Introduce Parameter Object(引入参数对象)将参数封装成对象。_

优化思路


1、观察经常一起出现的数据;

2、通过提炼类的方法,放到属于他们的对象中;

3、用对象来代替这些数据;

4、编译测试。

eg:未优化代码

例子参考一个优秀博主提供的例子

https://blog.youkuaiyun.com/geniusxi/article/details/78581542

public class Car{

// 奔驰

public void printBenz(String brand, String model, Integer price, double power) {

printBasicInfo(brand, model, price, power);

getTax(power, price);

}

// 宝马

public void printBmw(String brand, String model, Integer price, double power) {

printBasicInfo(brand, model, price, power);

getTax(power, price);

}

// 提炼打印基本信息方法

private void printBasicInfo(String brand, String model, Integer price, double power) {

System.out.println(“品牌” + brand);

System.out.println(“型号:” + model);

System.out.println(“动力:” + power);

System.out.println(“价格:” + price);

}

// 提炼计算税费的方法

private double getTax(double power, Integer price){

double salePrice = price;

if (price > 200000) {

salePrice = price * 0.98;

}

if (power <= 1.6) {

return salePrice * 0.05;

} else {

return salePrice * 0.1;

}

}

}

优化1,2步骤

最后,附一张自己面试前准备的脑图:

image

面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典

  • Java核心知识整理

image

  • Spring全家桶(实战系列)

image.png

Step3:刷题

既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。

以下是我私藏的面试题库:

image

很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。

最后祝愿各位身体健康,顺利拿到心仪的offer!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
.(img-c2erp3vs-1714775600342)]

面试前一定少不了刷题,为了方便大家复习,我分享一波个人整理的面试大全宝典

  • Java核心知识整理

[外链图片转存中…(img-kABuqRRY-1714775600343)]

  • Spring全家桶(实战系列)

[外链图片转存中…(img-whPIR3RV-1714775600343)]

Step3:刷题

既然是要面试,那么就少不了刷题,实际上春节回家后,哪儿也去不了,我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。

以下是我私藏的面试题库:

[外链图片转存中…(img-KVi8Y0MM-1714775600344)]

很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。

最后祝愿各位身体健康,顺利拿到心仪的offer!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值