Enum RPS实现在初始化器和非法前向引用中提供自引用

时间:2014-03-19 08:41:32

标签: java enums

我有以下代码,我相信我看到为什么我收到了错误:

错误例如是:

  • 初始化程序中的自引用位于ROCK的构造函数RPSGesture.ROCK
  • ROCK RPSGesture.PAPER的构造函数中的非法转发引用

public interface Gesture {
    public List<? extends Gesture> winsFrom();

    public List<? extends Gesture> tiesTo();

    public List<? extends Gesture> losesTo();
}

public enum RPSGesture implements Gesture, Action {
    ROCK(
        Arrays.asList(RPSGesture.SCISSORS),
        Arrays.asList(RPSGesture.ROCK),
        Arrays.asList(RPSGesture.PAPER)
    ),

    PAPER(
        Arrays.asList(RPSGesture.ROCK),
        Arrays.asList(RPSGesture.PAPER),
        Arrays.asList(RPSGesture.SCISSORS)
    ),

    SCISSORS(
        Arrays.asList(RPSGesture.PAPER),
        Arrays.asList(RPSGesture.SCISSORS),
        Arrays.asList(RPSGesture.ROCK)
    );

    private final List<RPSGesture> winsFrom;
    private final List<RPSGesture> tiesTo;
    private final List<RPSGesture> losesTo;

    private RPSGesture(final List<RPSGesture> winsFrom, final List<RPSGesture> tiesTo, final List<RPSGesture> losesTo) {
        this.winsFrom = winsFrom;
        this.tiesTo = tiesTo;
        this.losesTo = losesTo;
    }

    @Override
    public List<RPSGesture> winsFrom() {
        return winsFrom;
    }

    @Override
    public List<RPSGesture> tiesTo() {
        return tiesTo;
    }

    @Override
    public List<RPSGesture> losesTo() {
        return losesTo;
    }
}

我见过Peter Lawrey's Answer,但是static初始化程序真的是最好的方法吗?还有其他合理的选择吗?

这个枚举的设计看起来是否正确,或者您自己会采用不同的方式吗?希望课堂上的代码更少。

1 个答案:

答案 0 :(得分:1)

我自己找到了一种使用Java 8的正确方法:

public interface Gesture {
    public List<? extends Gesture> winsFrom();

    public List<? extends Gesture> tiesTo();

    public List<? extends Gesture> losesTo();
}

public enum RPSGesture implements Gesture, Action, RuleGestureFPSFactory {
    ROCK,
    PAPER,
    SCISSORS;

    @Override
    public List<RPSGesture> winsFrom() {
        return winMapping().get(this);
    }

    @Override
    public List<RPSGesture> tiesTo() {
        return tieMapping().get(this);
    }

    @Override
    public List<RPSGesture> losesTo() {
        return loseMapping().get(this);
    }
}

public interface RuleGestureFactory<T extends Gesture> {
    public Map<T, List<T>> winMapping();

    public Map<T, List<T>> tieMapping();

    public Map<T, List<T>> loseMapping();
}

public interface RuleGestureFPSFactory extends RuleGestureFactory<RPSGesture> {
    @Override
    default public Map<RPSGesture, List<RPSGesture>> winMapping() {
        Map<RPSGesture, List<RPSGesture>> mapping = new HashMap<>();
        mapping.put(ROCK, Arrays.asList(SCISSORS));
        mapping.put(PAPER, Arrays.asList(ROCK));
        mapping.put(SCISSORS, Arrays.asList(PAPER));
        return mapping;
    }

    @Override
    default public Map<RPSGesture, List<RPSGesture>> tieMapping() {
        Map<RPSGesture, List<RPSGesture>> mapping = new HashMap<>();
        mapping.put(ROCK, Arrays.asList(ROCK));
        mapping.put(PAPER, Arrays.asList(PAPER));
        mapping.put(SCISSORS, Arrays.asList(SCISSORS));
        return mapping;
    }

    @Override
    default public Map<RPSGesture, List<RPSGesture>> loseMapping() {
        Map<RPSGesture, List<RPSGesture>> mapping = new HashMap<>();
        mapping.put(ROCK, Arrays.asList(PAPER));
        mapping.put(PAPER, Arrays.asList(SCISSORS));
        mapping.put(SCISSORS, Arrays.asList(ROCK));
        return mapping;
    }
}

通过这种方式,您甚至可以轻松地实现不同的规则实现,但它不支持在运行时切换。