Java - Как правильно вызвать универсальный интерфейс с несколькими неявными реализациями - PullRequest
0 голосов
/ 22 октября 2019

У меня есть универсальный интерфейс с реализацией внутри него:

@FunctionalInterface
public interface PlayerPickStrategy<T> {

    static <T> PlayerPickStrategy<T> always1() {
        return new AlwaysOne<>();
    }

    int getNextPick(T lastResult);

    final class AlwaysOne<T> implements PlayerPickStrategy<T> {

        @Override
        public int getNextPick(T lastResult) {
            return 1;
        }
    }
}

Затем я получил две другие реализации этого в отдельных классах, которые неявно типизированы:

public class SimulationRunRandomFromPayoutsSizePlayerPickStrategy implements PlayerPickStrategy<Integer> {

    private final RandomRng randomRng = new RandomRng();

    public static SimulationRunRandomFromPayoutsSizePlayerPickStrategy random() {
        return new SimulationRunRandomFromPayoutsSizePlayerPickStrategy();
    }

    @Override
    public int getNextPick(Integer sizeOfPayouts) {
        return randomRng.getRandomNumber(false, 1, sizeOfPayouts);
    }
}

public class SimulationRunNextNodePlayerPickStrategy implements PlayerPickStrategy<IPlayResult> {

    private Map<String, Integer> picksForModes;

    SimulationRunNextNodePlayerPickStrategy(Map<String, Integer> picksForModes) {
        this.picksForModes = picksForModes;
    }

    static SimulationRunNextNodePlayerPickStrategy nextNode(Map<String, Integer> picksForModes) {
        return new SimulationRunNextNodePlayerPickStrategy(picksForModes);
    }

    @Override
    public int getNextPick(IPlayResult playResult) {
        String nextState = playResult.getNextState().toString();
        return picksForModes.get(nextState);
    }
}

Я сопоставляю вход String с одним из этих PlayerPickStrategies следующим образом:

public static PlayerPickStrategy getPlayerPickStrategy(String playerPickStrategy) {
    // RANDOM="1,2,3,4"
    // ALWAYS="2"
    // NEXT_MODE="gf44fdgf":"1","fgdfgdfgdf":"7"
    String[] playerPickStrategySplit = playerPickStrategy.split("=");
    return SimulationPicks.valueOf(playerPickStrategySplit[0]).getStrategy(playerPickStrategySplit[1]);
}

public enum SimulationPicks {
    RANDOM(s -> PlayerPickStrategy.randomOf(Arrays.stream(s.split(","))
                                              .map(Integer::parseInt)
                                              .collect(Collectors.toList()))),

    RANDOM_FROM(s-> SimulationRunRandomFromPayoutsSizePlayerPickStrategy.random()),

    FIXED_ORDER(s -> PlayerPickStrategy.randomOf(Arrays.stream(s.split(","))
                                                   .map(Integer::parseInt)
                                                   .collect(Collectors.toList()))),

    ALWAYS_N(s -> PlayerPickStrategy.always(Integer.parseInt(s))),

    NEXT_NODE(s -> SimulationRunNextNodePlayerPickStrategy.nextNode(Stream.of(s.split(","))
                                                              .map(it -> it.split(":"))
                                                              .collect(Collectors.toMap(it -> it[0].replace("\"", ""),
                                                                                        it -> Integer.parseInt(it[1])))));

    final Function<String, PlayerPickStrategy> mapper;

    SimulationPicks(Function<String, PlayerPickStrategy> mapper) {
        this.mapper = mapper;
    }

    public PlayerPickStrategy getStrategy(String input) {
        return mapper.apply(input);
    }
}

Таким образом, я получаю объект PlayerPickStrategy, который является одной из 3 реализаций интерфейса и имеет либо T, IPlayResult или Integer.

Однако, когда я пытаюсь вызвать getNextPick с IPlayResult для моего универсального PlayerPickStrategy, он вызывает исключение MethodNotFound для getNextPick (Object), так как метод getNextPick в PlayerPickStrategy ожидает TlastResult, а не IPlayResult.

  • Использую ли я универсальные интерфейсы совершенно неправильно?
  • Как я должен обрабатывать создание этих универсальных типов и вызов метода, который я 'Я ожидаю, что будет вести себя по-разному в зависимости от типа?
  • Как я должен знать, какой тип отправить его доя это называю? Мне может понадобиться отправить ему IPlayResult, или Integer, или вообще ничего, и как лучше всего справиться с этим? instanceof?

Это новая территория для меня, поэтому любая помощь будет принята с благодарностью.

...