2015-11-05 46 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