Java重构具有多态性的interlinked switch / if语句

时间:2016-12-09 14:46:10

标签: java switch-statement polymorphism refactoring

我知道如何通过多态来替换switch语句,就像例如here所解释的那样。

在我的情况下,我有两个枚举:

public enum EleType {
    INTEGER, 
    CHARACTER
}

public enum SorterType {
    BUBBLE,
    INSERTION
}

和switch /如果我想重构有结构:

if ( eleType == EleType.INTEGER ) {
    switch ( sorterType ) {
        case BUBBLE:
             composition = new SorterComposition<Integer>(new BubbleSort<Integer>(), randomList);
             break;
        case INSERTION:
             composition = new SorterComposition<Integer>(new InsertionSort<Integer>(), randomList);
             break;
    }
} else if ( eleType == EleType.CHARACTER ) {
    switch ( sorterType ) {
        case BUBBLE:
             composition = new SorterComposition<Character>(new BubbleSort<Character>(), randomList);
             break;
        case INSERTION:
             composition = new SorterComposition<Character>(new InsertionSort<Character>(), randomList);
             break;
    }
}

因为两个枚举一起出现并且都影响SorterComposition部分,所以我不确定如何重构这个结构。另外,我不确定如何在不使用条件语句的情况下分别从EleType.INTEGER或EleType.CHARACTER获取“整数”/“字符”泛型类型。

2 个答案:

答案 0 :(得分:1)

你的意思是你实现这样的代码吗?

public static <T> SorterComposition<T> createComposition(SorterType type, <Type of randomList>) {
    switch (type) {
        case BUBBLE:
            return new SorterComposition<T>(new BubbleSort<T>(), randomList);
        case INSERTION:
            return new SorterComposition<T>(new InsertionSort<T>(), randomList);
        default:
            throw <Exception>
    }
}

或者,您可以稍微更改EleType课程。

public enum EleType {
    INTEGER(Integer.class), CHARACTER(Character.class);
    private EleType(Class cl) { this.classType = cl; }
    public Class getClassType() { return classType; }
    private final Class classType;
}

并使用此代码代替上面的createComposition

public static <T> SorterComposition<T> createComposition(Class<T> eleType, SorterType type, <Type of randomList>) {
    switch (type) {
        case BUBBLE:
            return new SorterComposition<T>(new BubbleSort<T>(), randomList);
        case INSERTION:
            return new SorterComposition<T>(new InsertionSort<T>(), randomList);
        default:
            throw <Exception>
    }
}

当您使用它时,请使用composition = createComposition(eleType.getClassType(), sorterType, randomList);

要以温和的方式避免switch SorterType,也许您可​​以在Supplier中添加SorterType字段。

public enum SorterType {
    BUBBLE(() -> new BubbleSort()),
    INSERTION(() -> new InsertionSort());

    private SorterType(Supplier<Sort> supplier) {
        this.supplier = supplier;
    }

    public Sort getSort() {
        return supplier.get();
    }

    private final Supplier<Sort> supplier;
}

答案 1 :(得分:0)

您可以使用双重调度。我在下面提供了一个框架实现。 但有些人会考虑double dispatch a code smell.在这种情况下,你的EleType似乎对我很怀疑。在这个例子中你所做的就是将它用于你的泛型类型声明。

    public enum EleType {
    INTEGER {
        SorterComposition getSorter(SorterType s) {
            return s.getIntegerSorter();
        }
    }, 
    CHARACTER{
        SorterComposition getSorter(SorterType s) {
            return s.getChracterSorter();
        }

    };

    abstract SorterComposition getSorter(SorterType s);
};

public enum SorterType {
    BUBBLE {
        SorterComposition getIntegerSorter() {return new BubbleSort<Integer>();}
        SorterComposition getChracterSorter() {return new BubbleSort<Character>();}
    },
    INSERTION{
        SorterComposition getIntegerSorter() {return new InsertionSort<Integer>();}
        SorterComposition getChracterSorter() {return new InsertionSort<Character>();}
    };

    abstract SorterComposition getIntegerSorter();
    abstract SorterComposition getChracterSorter();

};