IDEA代码重构技巧--拆分类

IDEA代码重构技巧--目录页

1. 小声哔哔

    方法会腐化,同样,对象类也会腐化,不同人对业务理解的不同导致一个对象类可能被添加了很多不属于他的属性,这时就产生了代码的坏味道,此时我们需要将对象类拆分。

    示例代码


/**
 * @author: Coline
 * @ClassName: AirportCheckIn
 * @Date: 2022/8/20 23:28
 * @Description: 机场值机--只是抽取了部分作为案例,不做实际值机流程参考
 * 1.登机牌
 * 2.托运行李
 * 3.购买附加服务
 */
public class AirportCheckIn {
    /**
     * 登机牌
     * 1. 姓名
     * 2. 身份证号
     * 3. 航班号
     * 4. 出发地
     * 5. 到达地
     */
    private String name;
    private String idCard;
    private String flightNumber;
    private String fromAddress;
    private String toAddress;

    /**
     * 托运行李:
     * 1. 行李重量
     * 2. 托运费用
     * 3. 是否办理托运
     */
    private double luggageWeight;
    private double freight;
    private boolean isConsignment;

    /**
     * 购买增值服务
     * 1. 是否购买保险服务
     * 2. 保险价格
     * 3. 是否商务舱升舱
     * 4. 升舱价格
     */
    private boolean isInsurance;
    private double insurancePrice;
    private boolean isBusinessUpgrade;
    private double upgradePrice;

    public AirportCheckIn(String name, String idCard, String flightNumber, String fromAddress, String toAddress
            , double luggageWeight, double freight, boolean isConsignment, boolean isInsurance
            , double insurancePrice, boolean isBusinessUpgrade, double upgradePrice) {
        this.name = isEmpty(name, "name can not be null");
        this.idCard = idCard;
        this.flightNumber = flightNumber;
        this.fromAddress = fromAddress;
        this.toAddress = toAddress;
        this.luggageWeight = luggageWeight;
        this.freight = freight;
        this.isConsignment = isConsignment;
        this.isInsurance = isInsurance;
        this.insurancePrice = insurancePrice;
        this.isBusinessUpgrade = isBusinessUpgrade;
        this.upgradePrice = upgradePrice;
    }

    public String getName() {
        return name;
    }

    public String getIdCard() {
        return idCard;
    }

    public String getFlightNumber() {
        return flightNumber;
    }

    public String getFromAddress() {
        return fromAddress;
    }

    public String getToAddress() {
        return toAddress;
    }

    public double getLuggageWeight() {
        return luggageWeight;
    }

    public double getFreight() {
        return freight;
    }

    public boolean isConsignment() {
        return isConsignment;
    }

    public boolean isInsurance() {
        return isInsurance;
    }

    public double getInsurancePrice() {
        return insurancePrice;
    }

    public boolean isBusinessUpgrade() {
        return isBusinessUpgrade;
    }

    public double getUpgradePrice() {
        return upgradePrice;
    }

    public static String isEmpty(String input, String errMessage) {
        if (input == null) {
            throw new IllegalArgumentException(errMessage);
        }
        return input;
    }
}

2. 拆分类

    关注示例代码,我们发现其实可以将属性拆分到三个类:
    1. 登机牌信息
    2. 行李托运
    3. 增值服务
    拆分类我们要遵循一个原则,保留旧的,创建新的,切换新的,删除旧的,以此来减少出错的可能。

输入方法名,例如:AirportCheckIn

  •  步骤二:将参数抽象成新的类。选中方法,键入Shift+Ctrl+Alt+t,选择Introduct Parameter Object

    填入类名,选择创建内部类和要抽取的属性

    点击Refactor后就会创建内部内,创建完成后就会生成内部类如下图。

  • 步骤三: 选择抽取出的参数,Alt+回车 创建参数

  • 步骤四:添加this。因为后面要做内联替换,所以需要将=号后面的替换后参数前加上this。

    如果类似于下面这种不能直接this的

    选中参数,Ctrl+Alt+V抽取参数

    然后将对应的参数剪切复制到内部类的构造函数

 然后将原有调用点的String name改成this.name

  • 步骤六:对参数内联替换。首先选中待替换参数,键入Alt+回车,选择Make final,将参数设置为final的。

    选择参数,键入Ctrl+Alt +n

    内联替换完成后关注之前调用的地方发生了改变。

    依次将其他参数都设置为final,然后内联替换

  •  步骤七:将内部类移到预期位置。选择内部类,键入F6

     输入预期的包路径,这里可以手动输入,没有目标包的话会自动创建

  • 步骤九:去中间者。可以发现内联替换后还是存在中间者,类似下图

    点击参数 ,例如图中的boardingPass,键入Shift+Ctrl+Alt+t,选择Remove Middleman

    点击Refactor后发现效果是会删除本类中中间存在的get方法,然后可以选择性的创建boardingPass的get方法,选中参数,键入Alt+INS。

 最终结果我们可以生成4个类。AirportCheckIn,ValueAdd,BoardingPass,Baggage


/**
 * @author: Coline
 * @ClassName: Baggage
 * @Date: 2022/8/23 23:46
 * @Description: 行李托运
 */
public class Baggage {
    private final double luggageWeight;
    private final double freight;
    private final boolean isConsignment;

    public Baggage(double luggageWeight, double freight, boolean isConsignment) {
        this.luggageWeight = luggageWeight;
        this.freight = freight;
        this.isConsignment = isConsignment;
    }

    public double getLuggageWeight() {
        return luggageWeight;
    }

    public double getFreight() {
        return freight;
    }

    public boolean isConsignment() {
        return isConsignment;
    }
}

import com.coline.actual.AirportCheckIn;

/**
 * @author: Coline
 * @ClassName: BoardingPass
 * @Date: 2022/8/23 23:21
 * @Description: 登机牌
 */
public class BoardingPass {
    private final String name;
    private final String idCard;
    private final String flightNumber;
    private final String fromAddress;
    private final String toAddress;

    public BoardingPass(String name, String idCard, String flightNumber, String fromAddress, String toAddress) {
        this.name = AirportCheckIn.isEmpty(name, "name can not be null");
        this.idCard = idCard;
        this.flightNumber = flightNumber;
        this.fromAddress = fromAddress;
        this.toAddress = toAddress;
    }

    public String getName() {
        return name;
    }

    public String getIdCard() {
        return idCard;
    }

    public String getFlightNumber() {
        return flightNumber;
    }

    public String getFromAddress() {
        return fromAddress;
    }

    public String getToAddress() {
        return toAddress;
    }
}

/**
 * @author: Coline
 * @ClassName: ValueAdd
 * @Date: 2022/8/23 23:51
 * @Description: 增值服务
 */
public class ValueAdd {
    private final boolean isInsurance;
    private final double insurancePrice;
    private final boolean isBusinessUpgrade;
    private final double upgradePrice;

    public ValueAdd(boolean isInsurance, double insurancePrice, boolean isBusinessUpgrade, double upgradePrice) {
        this.isInsurance = isInsurance;
        this.insurancePrice = insurancePrice;
        this.isBusinessUpgrade = isBusinessUpgrade;
        this.upgradePrice = upgradePrice;
    }

    public boolean isInsurance() {
        return isInsurance;
    }

    public double getInsurancePrice() {
        return insurancePrice;
    }

    public boolean isBusinessUpgrade() {
        return isBusinessUpgrade;
    }

    public double getUpgradePrice() {
        return upgradePrice;
    }
}
import com.coline.actual.model.Baggage;
import com.coline.actual.model.BoardingPass;
import com.coline.actual.model.ValueAdd;

/**
 * @author: Coline
 * @ClassName: AirportCheckIn
 * @Date: 2022/8/20 23:28
 * @Description: 机场值机--只是抽取了部分作为案例,不做实际值机流程参考
 * 1.登机牌
 * 2.托运行李
 * 3.购买附加服务
 */
public class AirportCheckIn {
    private BoardingPass boardingPass;
    private Baggage baggage;
    private ValueAdd valueAdd;

    public AirportCheckIn(BoardingPass boardingPass, Baggage baggage, ValueAdd valueAdd) {
        this.boardingPass = boardingPass;
        this.baggage = baggage;
        this.valueAdd = valueAdd;

    }

    public static String isEmpty(String input, String errMessage) {
        if (input == null) {
            throw new IllegalArgumentException(errMessage);
        }
        return input;
    }

    public BoardingPass getBoardingPass() {
        return boardingPass;
    }

    public void setBoardingPass(BoardingPass boardingPass) {
        this.boardingPass = boardingPass;
    }

    public Baggage getBaggage() {
        return baggage;
    }

    public void setBaggage(Baggage baggage) {
        this.baggage = baggage;
    }

    public ValueAdd getValueAdd() {
        return valueAdd;
    }

    public void setValueAdd(ValueAdd valueAdd) {
        this.valueAdd = valueAdd;
    }
}

相关文章

学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习...
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面...
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生...
Can’t connect to local MySQL server through socket \'/v...
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 ...
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服...