英文:
How to avoid instanceof from this kind of case?
问题
以下是翻译好的代码部分:
在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);
}
类:
抽象类 SkillCard 扩展自 Card,同时实现 PoweredCard 接口
类 CharacterCard 扩展自 Card,同时实现 PoweredCard 和 PutableCard 接口
类 LandCard 扩展自 Card
但是,肯定不能正常工作,因为它没有检查所有情况...
在这种情况下,是否可能避免使用 instanceof 而改用多态性呢?
英文:
My current code in Player.java is like this:
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()]);
}
I want to avoid using of multiple instanceofs here because of what they call it "code smells" and use polymorphism instead. So what I can do is to rewrite it to be like this:
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);
}
classes:
abstract class SkillCard extends Card implements PoweredCard
class CharacterCard extends Card implements PoweredCard, PutableCard
class LandCard extends Card
But, surely it won't work because it doesn't check every cases..
Is it possible to avoid instanceof and use polymorphism instead in this case?
答案1
得分: 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);
}
}
// ... 以此类推。Player类将需要必要的查询方法。
英文:
Instanceof operator can usually be replaced with proper reliance on java virtual dispatch. Move decision logic to Card class, like this
public abstract boolean canPutCard(Player player);
And then implement appropriate logic in Card subclasses like:
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);
}
}
... and so on. Player class will need to have required query methods.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论