Java重构多区间if语句

139 阅读1分钟

使用责任链和构造类的方法降低多条件if语句的圈复杂度。 场景:根据对象年龄判断年龄阶段,有如下5种情况。童年(0-6),少年(7-17),青年(18-40),中年(41-65),老年(>66)。因此if语句需要有5个分支和return语句会增加函数的圈复杂度。 重构前代码如下: 年龄范围枚举类

public enum AgeRangeEnum {
    CHILD_MIN(0),
    CHILD_MAX(6),
    TEEN_MIN(7),
    TEEN_MAX(17),
    YOUNG_MIN(18),
    YOUNG_MAX(40),
    MIDDLE_MIN(41),
    MIDDLE_MAX(65),
    OLD_MIN(66),
    OLD_MAX(Integer.MAX_VALUE);

    private final Integer age;

    AgeRangeEnum(Integer age) {
        this.age = age;
    }

    public Integer getValue() {
        return age;
    }
}

年龄阶段枚举类

public enum StageEnum {
    CHILD("童年"),
    TEEN("少年"),
    YOUNG("青年"),
    MIDDLE("中年"),
    OLD("老年");

    private final String stage;
    StageEnum(String stage){
        this.stage = stage;
    }
    public String getStage(){
        return stage;
    }
}

重构前的函数

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class Human {
    private Integer age;
    // 重构前,多区间范围查询判断
    public String getStageByAge(){
        if(isChild()){
            return StageEnum.CHILD.getStage();
        }
        if(isTeen()){
            return StageEnum.TEEN.getStage();
        }
        if(isYoung()){
            return StageEnum.YOUNG.getStage();
        }
        if(isMiddle()){
            return StageEnum.MIDDLE.getStage();
        }
        return StageEnum.OLD.getStage();
    }
    public boolean isChild(){
        return age >= AgeRangeEnum.CHILD_MIN.getValue() && age <= AgeRangeEnum.CHILD_MAX.getValue();
    }
    public boolean isTeen(){
        return age >= AgeRangeEnum.TEEN_MIN.getValue() && age <= AgeRangeEnum.TEEN_MAX.getValue();
    }
    public boolean isYoung(){
        return age >= AgeRangeEnum.YOUNG_MIN.getValue() && age <= AgeRangeEnum.YOUNG_MAX.getValue();
    }
    public boolean isMiddle(){
        return age >= AgeRangeEnum.MIDDLE_MIN.getValue() && age <= AgeRangeEnum.MIDDLE_MAX.getValue();
    }
    public boolean isOld(){
        return age > AgeRangeEnum.OLD_MIN.getValue() && age <= AgeRangeEnum.OLD_MAX.getValue();
    }
}

使用构造类进行重构

自定义AgeRange类,属性包括年龄段上下限和阶段描述,一个方法判断给定年龄是否在当前范围内,提供静态方法给外部类调用通过年龄来获取当前年龄阶段,静态属性初始化AgeRange数组。

public class AgeRange {
    private static final AgeRange[] AGE_RANGES = {
            new AgeRange(AgeRangeEnum.CHILD_MIN.getValue(), AgeRangeEnum.CHILD_MAX.getValue(), StageEnum.CHILD.getStage()),
            new AgeRange(AgeRangeEnum.TEEN_MIN.getValue(), AgeRangeEnum.TEEN_MAX.getValue(), StageEnum.TEEN.getStage()),
            new AgeRange(AgeRangeEnum.YOUNG_MIN.getValue(), AgeRangeEnum.YOUNG_MAX.getValue(), StageEnum.YOUNG.getStage()),
            new AgeRange(AgeRangeEnum.MIDDLE_MIN.getValue(), AgeRangeEnum.MIDDLE_MAX.getValue(), StageEnum.MIDDLE.getStage()),
            new AgeRange(AgeRangeEnum.OLD_MIN.getValue(), AgeRangeEnum.OLD_MAX.getValue(), StageEnum.OLD.getStage())
    };
    private final Integer MIN;
    private final Integer MAX;
    private final String STAGE;

    private AgeRange(Integer min, Integer max, String stage) {
        this.MIN = min;
        this.MAX = max;
        this.STAGE = stage;
    }

    public static String getSTAGE(Integer age) {
        for (AgeRange ageRange : AGE_RANGES) {
            if (ageRange.contains(age)) {
                return ageRange.STAGE;
            }
        }
        return null;
    }

    private boolean contains(Integer age) {
        return age >= MIN && age <= MAX;
    }
}

外部调用:

public class Human {
    private Integer age;
    // 构造类重构
    public String getStageByAge(){
        return AgeRange.getSTAGE(age);
    }
}

使用责任链模式进行重构

StageHandler抽象类:

public abstract class StageHandler {
    protected StageHandler nextHandler;

    public void setNextHandler(StageHandler nextHandler){
        this.nextHandler = nextHandler;
    }

    public abstract String handle(Integer age);
}

需要写五个处理类,以ChildStageHandler为例:

@NoArgsConstructor
public class ChildStageHandler extends StageHandler {
    @Override
    public String handle(Integer age) {
        if (isChild(age)) {
            return StageEnum.CHILD.getStage();
        } else {
            return nextHandler.handle(age);
        }
    }
    public boolean isChild(Integer age) {
        return age >= AgeRangeEnum.CHILD_MIN.getValue() && age <= AgeRangeEnum.CHILD_MAX.getValue();
    }
}

主方法构造处理链调用:

public class Human {
    private Integer age;

    // 责任链重构
    public String getStageByAge() {
        ChildStageHandler childStageHandler = new ChildStageHandler();
        TeenStageHandler teenStageHandler = new TeenStageHandler();
        YoungStageHandler youngStageHandler = new YoungStageHandler();
        MiddleStageHandler middleStageHandler = new MiddleStageHandler();
        OldStageHandler oldStageHandler = new OldStageHandler();
        childStageHandler.setNextHandler(teenStageHandler);
        teenStageHandler.setNextHandler(youngStageHandler);
        youngStageHandler.setNextHandler(middleStageHandler);
        middleStageHandler.setNextHandler(oldStageHandler);

        return childStageHandler.handle(age);
    }
}