2015-11-05 50 views
0

我正在开发一个模拟大量修改的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

我不知道为什么你有3个完全相同的枚举命名不同。这里是重构代码:

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; 
     } 

    } 

} 

这是否适合您?

+0

这是美丽的,先生,你是上帝。我对Java还比较陌生,而且我几乎没有使用函数式编程的经验,所以我从来没有想过这种解决方案,但这是一个很好的例子。谢谢 :) – BrainFRZ