使用嵌套枚举重构方法

时间:2015-11-05 22:33:35

标签: java enums refactoring

我正在开发一个模拟经过大量修改的DnD 3.5的项目。现在,我正在从事专业(课程,但我不希望与class混淆),特别是关于豁免检定。现在,我为每个职业都有一个枚举,每个成员都使用一个构造函数来指定每种保存是好还是差,这在嵌套枚举中表示。但是,计算修饰符的方法基本相同,只是它们在不同的保存投掷上使用switch

有没有办法重构接受父枚举的方法作为方法的参数之一,然后检查嵌套枚举的值?

public enum Profession {
    BARBARIAN   (WillSave.POOR, FortitudeSave.GOOD, ReflexSave.POOR),
    BARD        (WillSave.GOOD, FortitudeSave.POOR, ReflexSave.GOOD),
    CLERIC      (WillSave.GOOD, FortitudeSave.GOOD, ReflexSave.POOR);


    private static int goodSaveModifier(int level) {
        return ((level / 2) + 2);
    }

    private static int poorSaveModifier(int level) {
        return (level / 3);
    }



    /**
     * Generates the given ProfessionType
     *
     * @param wil <code>WillSave.STRONG</code> if profession has a good will save, or
     * <code>POOR</code> otherwise
     * @param fort <code>FortitudeSave.STRONG</code> if profession has a good fortitude save, or
     * <code>POOR</code> otherwise
     * @param ref <code>ReflexSave.STRONG</code> if profession has a good reflex save, or
     * <code>POOR</code> otherwise
     */
    Profession(WillSave wil, FortitudeSave fort, ReflexSave ref) {
        will = wil;
        fortitude = fort;
        reflex = ref;
    }


    /**
     * Calculates the Profession's Fortitude modifier.
     *
     * @param level Character's current level
     * @return Profession's modifier of the WillSave save
     * @throws IndexOutOfBoundsException If saving throw strength isn't valid
     */
    public int willModifier(int level) {
        int modifier;

        switch(will) {
            case GOOD:
                modifier = goodSaveModifier(level);
                break;
            case POOR:
                modifier = poorSaveModifier(level);
                break;
            default:
                throw new IndexOutOfBoundsException("Save type " + will.name() + " doesn't exist.");
        }

        return modifier;
    }

    /**
     * Calculates the Profession's Fortitude modifier.
     *
     * @param level Character's current level
     * @return Profession's modifier of the FortitudeSave save
     * @throws IndexOutOfBoundsException If saving throw strength isn't valid
     */
    public int fortitudeModifier(int level) {
        int modifier;

        switch(fortitude) {
            case GOOD:
                modifier = goodSaveModifier(level);
                break;
            case POOR:
                modifier = poorSaveModifier(level);
                break;
            default:
                throw new IndexOutOfBoundsException("Save type " + fortitude.name()
                                                            + " doesn't exist.");
        }

        return modifier;
    }

    /**
     * Calculates the Profession's Reflex modifier.
     *
     * @param level Character's current level
     * @return Profession's modifier of the ReflexSave save
     * @throws IndexOutOfBoundsException If saving throw strength isn't valid
     */
    public int reflexModifier(int level) {
        int modifier;

        switch(reflex) {
            case GOOD:
                modifier = goodSaveModifier(level);
                break;
            case POOR:
                modifier = poorSaveModifier(level);
                break;
            default:
                throw new IndexOutOfBoundsException("Save type " + reflex.name()
                                                            + " doesn't exist.");
        }

        return modifier;
    }


    private final WillSave will;
    private final FortitudeSave fortitude;
    private final ReflexSave reflex;




    private enum WillSave {
        GOOD, POOR;
    }

    private enum FortitudeSave {
        GOOD, POOR;
    }

    private enum ReflexSave {
        GOOD, POOR;
    }
}

我能想到的只是另一个嵌套的枚举,让我们说SavingThrow.WILL作为一个例子,我不能想到如何指定参数中的哪个抛出,因为在这种情况下,签名就像calculateModifier(SavingThrow save, int level) : int一样,并且它不会起作用。无论如何,这是我的尝试,虽然它显然会抛出诸如WILL之类的保存而不是GOOD之类的值。有没有办法彻底重构这样的东西?

public int calculateModifier(SavingThrow save, int level) {
    int modifier;

    switch(save) {
        case GOOD:
            modifier = goodSaveModifier(level);
            break;
        case POOR:
            modifier = poorSaveModifier(level);
            break;
        default:
            throw new IndexOutOfBoundsException("Save type " + save.name()
                                                        + " doesn't exist.");
    }

    return modifier;
}


private final SavingThrow.WILL will;
private final SavingThrow.FORTITUDE fortitude;
private final SavingThrow.REFLEX reflex;



private enum SavingThrow {
    WILL {
        GOOD, POOR;
    },

    FORTITUDE {
        GOOD, POOR;
    },

    REFLEX {
        GOOD, POOR;
    };
}

1 个答案:

答案 0 :(得分:1)

我不确定为什么你有三个相同的枚举名称不同。这是重构的代码:

public enum Profession {
    BARBARIAN   (Save.POOR, Save.GOOD, Save.POOR),
    BARD        (Save.GOOD, Save.POOR, Save.GOOD),
    CLERIC      (Save.GOOD, Save.GOOD, Save.POOR);

    private final Save will;
    private final Save fortitude;
    private final Save reflex;

    Profession(Save will, Save fortitude, Save reflex) {
        this.will = will;
        this.fortitude = fortitude;
        this.reflex = reflex;
    }

    public int willModifier(int level) {
        return will.modifier.apply(level);
    }

    public int fortitudeModifier(int level) {
        return fortitude.modifier.apply(level);
    }

    public int reflexModifier(int level) {
        return reflex.modifier.apply(level);
    }

    private enum Save {

        GOOD(level -> level / 2 + 2),
        POOR(level -> level / 3);

        private final Function<Integer, Integer> modifier;

        Save(Function<Integer, Integer> modifier) {
            this.modifier = modifier;
        }

    }

}

这对你有用吗?