Как я могу избежать проверки типов в этой ситуации - PullRequest
2 голосов
/ 27 февраля 2020

Ситуация следующая:

У нас есть игра, в которой есть игроки и предметы. Игра выиграна, когда у игрока есть все 3 указанных c предмета в его инвентаре и он их собирает (на карте есть только 1 из них). Элементы имеют очень простой интерфейс, игрок может вызвать на них use(). Существуют другие классы, реализующие интерфейс Item, которые были исключены из фрагмента. Если бы я игнорировал основные принципы c OOP, я мог бы просто сказать, что когда игрок использует один из них, мы перебираем инвентарь игрока и проверяем, есть ли в нем все 3 из этих указанных c типов предметов. Как мне избежать этого?

public interface Item{
    public void use();
}

public class SpecificItem1 implements Item{
    public void use(){...}
}

public class SpecificItem2 implements Item{
    public void use(){...}
}

public class SpecificItem3 implements Item{
    public void use(){...}
}

public class Player{

    ArrayList<Item> inventory;

    public void didWeWin() {

        int numOfSItems = 0;

        for(Item i : inventory) {
            if(i instanceOf SpecificItem1)
                numOfSItems++;
            if(i instanceOf SpecificItem2)
                numOfSItems++;
            if(i instanceOf SpecificItem3)
                numOfSItems++;
        }

        if(numOfSItems == 3)
            win();
    }

}

Ответы [ 2 ]

4 голосов
/ 27 февраля 2020

Вы можете использовать getClass(), чтобы получить класс предмета, а затем посчитать количество уникальных:

public void didWeWin() {
   if (inventory.stream().map(Object::getClass).distinct().count() == 3L) {
       win();
   }
}
0 голосов
/ 27 февраля 2020

В случае, если инвентарь может содержать другие виды предметов, которые не являются частью условия выигрыша, недостаточно проверить наличие по крайней мере трех разных предметов. В этом случае вы можете использовать метод containsAll для проверки классов предметов, необходимых для условия выигрыша.

// List.of works in Java 9+, use Arrays.asList for Java 8
private static List<Class<?>> WIN_CONDITION
    = List.of(SpecificItem1.class, SpecificItem2.class, SpecificItem3.class);

public boolean hasWon() {
    return inventory.stream()
        .map(Object::getClass)
        .collect(Collectors.toSet())
        .containsAll(WIN_CONDITION);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...