重构-函数

228 阅读2分钟

提取函数

import java.util.Random;

public class Main {
    
    public void PK(String attack,String defence,int pkSize){
        System.out.println(attack);
        System.out.println(defence);

        int attackWin = 0;
        int defenceWin = 0;
        Random random = new Random();
        for (int i = 0; i < pkSize; i++) {
            int randomNum = random.nextInt();
            if(randomNum % 2 == 0){
                attackWin++;
                continue;
            }
            defenceWin++;
        }

        if(attackWin > defenceWin){
            System.out.println(attack+"win--->"+attackWin);
            return;
        }
        if(attackWin < defenceWin){
            System.out.println(defence+"win--->"+defenceWin);
            return;
        }
        System.out.println("draw");
    }
}

函数要尽量短小,见名知意。

  • 复用几率大
  • 可读性强
  • 重写容易

无局部变量的代码段可以直接提取函数。

有局部变量的代码段。

  • 未修改局部变量,把局部变量作为提取函数的参数。
  • 修改局部变量,如果局部变量能只在提取函数使用,把这个局部变量放到提取函数里;如果不止在提取函数使用,把这个局部变量作为提取函数的参数。

对象取代临时变量

一个超大型函数,里边的临时变量让你无法直接提取函数。

此时可以把函数里的所有变量,参数,封装到一个新对象的属性里,在这个新对象里,就可以提取函数了。

函数替代临时变量

临时变量只能在当前函数作用域内使用,把临时变量用函数代替,可以在整个类使用。

临时变量只赋值一次

临时变量多次赋值,会令代码阅读这糊涂。临时变量应该只赋值一次。

循环变量、结果收集变量可以多次赋值。

不要修改参数的值

值类型的参数不要修改它的值。

引用类型的参数不要改变它指向的对象。

重构结果

public class Main {

    private Winner winner;

    public void PK(String attack,String defence,int pkSize){
        //对象取代临时变量
        winner = new Winner(this,attack,defence,pkSize);
        printUser();
        countWinTimes();
        printResult();
    }

    /**
     * 修改局部变量,如果局部变量能只在提取函数使用,把这个局部变量放到提取函数里
     */
    private void printUser(){
        System.out.println(winner.getAttack());
        System.out.println(winner.getDefence());
    }

    private void countWinTimes(){
        winner.compute();
    }

    private void printResult(){
        //getter,函数替代临时变量
        if(winner.getAttackWin() > winner.getDefenceWin()){
            System.out.println(winner.getAttack()+"win--->"+winner.getAttackWin());
            return;
        }
        if(winner.getAttackWin() < winner.getDefenceWin()){
            System.out.println(winner.getDefence()+"win--->"+winner.getDefenceWin());
            return;
        }
        System.out.println("draw");
    }

}
import lombok.Data;

import java.util.Random;

@Data
public class Winner {
    //要持有源对象
    private Main main;

    private String attack;

    private String defence;

    private int pkSize;

    private int attackWin;

    private int defenceWin;

    public Winner(Main main, String attack, String defence, int pkSize) {
        this.main = main;
        this.attack = attack;
        this.defence = defence;
        this.pkSize = pkSize;
    }

    public void compute(){
        Random random = new Random();
        for (int i = 0; i < pkSize; i++) {
            int randomNum = random.nextInt();
            if(randomNum % 2 == 0){
                attackWin++;
                continue;
            }
            defenceWin++;
        }

    }
}