简体   繁体   中英

How to reference enum fields from within Builder of another class?

I'm using a Builder pattern to create Item objects in my game, and I want to be able to use item prefixes and suffixes to generate random Items, as in Item.builder().random().build() . Prefix and Suffix are both enums with ragged fields. All of them have a name , but some have damage and luck fields, for example. How do I access the enums' fields from within the builder?

I have public methods in each enum that return a random Prefix and Suffix, my Item Builder's randomize method calls these and stores the affixes locally. But I can't seem to get at their member variables via reflection. prefix.getClass().getDeclaredField("name").toString returns java.lang.String roan.ItemPrefix$2.name instead of it's actual name. Plus it seems hacky to me.

Enum:

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
...

Ideally it would assemble a fully-formed items using the member fields of the enums passed to it. I'm using enum Prefix rather than an array of Prefix objects because I want to use certain EnumSets elsewhere for subclasses of Item like Armor , which can only use certain prefixes.

Your current design depends on 3 anonymous subclasses of the enum Prefix. This is not necessary. Rather try this:

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

  ...
}

Consequently you will not need reflection to access your fields.

If you really want the alternatives arrogant , bloody , curious to have different schemas, the decision for an enum is wrong. Rather select random in a list of factories, each returning the completely correct configured item for this random selection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM