重构:重新组织函数



一、将一段代码放进独立的函数中

1.1 代码示例

在这里插入图片描述

1.2 应用场景

当有一个过长的函数或者一段需要注释才能让人理解用途的代码,就将这段代码放进一个独立的函数中。

1.3 好处

首先,函数之间彼此复用的机会更大;其次,函数覆写(override)也更容易。

二、在函数调用点插入函数本体,然后移除该函数

2.1 代码示例

代码如下(示例):

在这里插入图片描述

2.2 应用场景

有时候遇到某些函数,其内部代码和函数名称同样清晰易读,此时应该去掉这个函数,直接使用其中的代码,间接性可能带来帮助,但非必要的间接性总是让人不舒服。

另一种情况就是:有一群组织不合理的函数,可以将它们都移到一个大型函数中,再从中提炼出组织合理的小函数。比起既要移动一个函数,又要移动它所调用的其它所有函数,将大型函数作为单一整体来移动会比较简单。

2.3 好处

如果别人使用了太多的间接层,使得系统中的所有函数都似乎只是对另一个函数的简单委托,造成我们在这些委托中晕头转向,通常会使用此方法。
间接层有其价值,但不是所有的简介层都有价值,我们可以将那些无用的简介层去除。

三、针对每次赋值,创造一个独立的、对应的临时变量

3.1 代码示例

在这里插入图片描述

3.2 应用场景和好处

临时变量有各种不同的用途,其中某些用途会导致临时变量被多次赋值,“循环变量”和“集用循环变量”是两个典型的例子。
循环变量会随循环的运行而改变,例如for (int i = 0; i < 10; i++)中的i;
集用循环变量负责将【通过整个函数的运算】而构成的某个值收集起来。

除了这两种情况,还有很多临时变量用于保存一段冗长代码的运算结果,以便稍后使用。这种变量应该只被赋值一次。
如果它们被赋值超过一次,就意味着它们再函数中承担了一个以上的责任。如果临时变量承担多个责任,它就应该被替换为多个临时变量,每个变量只承担一个责任。
同一个临时变量承担两件不同的事情,会令代码阅读者糊涂。

三、以一个临时变量取代某个参数的位置

3.1 代码示例

在这里插入图片描述

3.2 应用场景和好处

把一个对象作为参数传给某个函数,“对参数赋值”就是使该参数引用(指向)另一个对象。如果对被传入对象本身进行操作,那没问题,但是该对象被指向完全不同的另外一个对象,就可能会出问题,例如:

void avethoa(Object foo){
	foo.modifySomeWay(); //that's OK
	foo = anotherObject;  //trouble will follow you
}

之所以不喜欢这样使用,因为它降低了代码的清晰度,而且混淆了传值和传址这两种参数传递方式。
Java只采用传值。下面来看一段代码:

public class CSDN {
    public static void main(String[] args) {
        int x = 1;
        triple(x);
        System.out.println("主函数中调用triple之后的x:"+x);
    }

    private static void triple(int x) {
        x = x * 3;
        System.out.println("triple之后的x:"+ x);
    }
}

输出结果:
在这里插入图片描述
如果参数中传递的使对象,可能就会让人糊涂,例如:

import java.util.Date;
public class CSDN {
    public static void main(String[] args) {
        Date data1 = new Date();
        nextDateUpdate(data1);
        System.out.println("date1 after nextDateUpdate:"+data1);

        Date data2 = new Date();
        nextDateReplace(data2);
        System.out.println("date1 after nextDateReplace:"+data2);
    }
    private static void nextDateUpdate(Date data1) {
        data1.setDate(data1.getDate()+1);
        System.out.println("date1 in nextDateUpdate"+data1);
    }
    private static void nextDateReplace(Date data2) {
        data2 = new Date(data2.getYear(),data2.getMonth(),data2.getDate()+1);
        System.out.println("date1 in nextDateReplace"+data2);
    }
}

输出结果:
在这里插入图片描述
从本质上说,对象引用时按值传递的,因此我们可以修改参数对象的内部状态,但对参数对象重新赋值没有意义。

四、将函数本体替换为另一个算法

4.1 代码示例

在这里插入图片描述

4.2 应用场景和好处

有时候会发现,在原先做法之外有更简单的解决方案,此时就要改变原先的算法。
有时候会想要修改原先的算法,让它去做一件与原先动作略有差异的事,这时也可以先把原来的算法替换称为一个较易修改的算法,这样后续修改会轻松很多。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值