如何避免这种情况下的instanceof?

时间:2020-04-08 19:20:59

标签: java oop design-patterns polymorphism

我在Player.java中的当前代码如下:

    public boolean canPutCard(Card card) {
        if (!handCards.contains(card)) {
            return false;
        }
        if (card instanceof ActivableCard) {
            boolean hasEmpty = false;
            int i = card instanceof CharacterCard ? 0 : 1;
            for (int j = 0; j < fieldCards[i].length; ++j) {
                if (fieldCards[i][j] == null) {
                    hasEmpty = true;
                }
            }
            if (!hasEmpty) {
                return false;
            }
        }
        return (card instanceof LandCard && !hasPutLandCard) || (card instanceof PoweredCard
                && ((PoweredCard) card).getPowerNeeded() <= currentElementValue[card.getElementType().ordinal()]);
    }

我想避免在这里使用多个instanceof,因为它们称之为“代码气味”,而改用多态。所以我可以做的就是这样重写它:

    public boolean canPutCard(LandCard card) {
        return !hasPutLandCard;
    }

    public boolean canPutCard(PoweredCard card) {
        return card.getPowerNeeded() <= currentElementValue[card.getElementType().ordinal()];
    }

    private boolean canPutCard(int i, PutableCard card) {
        boolean hasEmpty = false;
        for (int j = 0; j < fieldCards[i].length; ++j) {
            if (fieldCards[i][j] == null) {
                hasEmpty = true;
            }
        }
        return hasEmpty;
    }

    public boolean canPutCard(PutableCard card) {
        return canPutCard(1, card);
    }

    public boolean canPutCard(CharacterCard card) {
        return canPutCard(0, card);
    }

    public boolean canPutCard(Card card) {
        return handCards.contains(card);
    }

课程:

abstract class SkillCard extends Card implements PoweredCard
class CharacterCard extends Card implements PoweredCard, PutableCard
class LandCard extends Card

但是,肯定不会起作用,因为它不会检查所有情况。

在这种情况下是否可以避免instanceof并改用多态性?

1 个答案:

答案 0 :(得分:1)

Instanceof运算符通常可以替换为对Java虚拟调度的适当依赖。将决策逻辑移至Card类,就像这样

public abstract boolean canPutCard(Player player);

然后在Card子类中实现适当的逻辑,例如:

class LandCard extends Card {
    @Override public boolean canPutCard(Player player) {
         return !player.hasPutLandCard() && player.handContains(this);
    }
}

class CharacterCard extends Card implements PoweredCard, PutableCard {
    @Override public boolean canPutCard(Player player) {
         return !player.hasEmptyCharacterCardField() && player.handContains(this);
    }
}

...等等。播放器类将需要具有必需的查询方法。

相关问题