如何从另一个类的Builder中引用枚举字段?

时间:2019-01-10 22:33:10

标签: java generics builder

我正在使用Builder模式在游戏中创建Item对象,并且我希望能够使用Item前缀和后缀来生成随机Item,如Item.builder().random().build()中所示。前缀和后缀都是带有参差不齐字段的枚举。例如,它们全部都有一个name,但是有些具有damageluck字段。如何在构建器中访问枚举的字段?

我在每个枚举中都有返回随机前缀和后缀的公共方法,我的Item Builder的randomize方法调用这些方法并将其存储在本地。但是我似乎无法通过反射来了解它们的成员变量。 prefix.getClass().getDeclaredField("name").toString返回java.lang.String roan.ItemPrefix$2.name而不是其实际名称。另外,对我来说似乎很黑。

枚举:

enum Prefix {
    ARROGANT {
        String name = "Arrogant ";
        int damage = 20;
        int luck = 2;
    },
    BLOODY {
        String name = "Bloody ";
        int damage = 30;
    },
    CURIOUS {
        String name = "Curious ";
        int luck = 4;
    },

    private static final int size = Prefix.values().length;

    public static Prefix randomPrefix() {
        return Prefix.values()[Dice.roll(Prefix.size)];
    }
}

Builder:

public static abstract class Builder<T extends Builder<T>> {
    // Default values
    private String name = "itemName"; 
    private int damage = 5;
    private int luck = 0;  

    protected abstract T self();

    public T name(String name) {
        this.name = name;
        return self();
    }

    // More builder methods
    ...

    // PROBLEMATIC CODE
    public T random() {
        Prefix prefix = Prefix.randomPrefix();
        this.name = prefix.getClass().getDeclaredField("name").toString();
        return self();
        }

        public Item build() {
            return new Item(this);
        }
    }
}

// Builder helper classes
...

理想情况下,它将使用传递给它的枚举的成员字段组装一个完整的项目。我使用enum Prefix而不是使用Prefix对象数组,因为我想在其他地方为Item之类的Armor的子类使用某些EnumSet,这些子类只能使用某些前缀。

1 个答案:

答案 0 :(得分:2)

您当前的设计取决于枚举Prefix的3个匿名子类。这不是必需的。而是尝试以下方法:

enum Prefix {
  ARROGANT ("Arrogant ",20,2), BLOODY("Bloody ",30,0), CURIOUS("Curious ",5, 4);

  public String name = "itemName"; 
  public int damage = 5;
  public int luck = 0;  

  Prefix(String name, int damage, int luck) {
    this.name = name;
    this.damage = damage;
    this.luck = luck;
  }

  ...
}

因此,您将不需要反思即可访问您的字段。

如果您确实希望替代项arrogantbloodycurious具有不同的架构,则枚举的决定是错误的。而是在工厂列表中选择随机变量,每个工厂都为此随机选择返回完全正确的配置项。