Reputation: 9599
Assuming I have the following code:
public boolean doesElfLikeIt ( Monster mon )
{
if ( mon instanceof Orc ) { return false; }
if ( mon instanceof Elf ) { return true; }
}
Is this a good programming approach or should I rather go for something like this:
public boolean doesElfLikeIt ( Monster mon )
{
if ( mon.getType() == Orc.type ) { return false; }
if ( mon.getType() == Elf.type ) { return true; }
}
The reason why I'm asking this is because I hear a lot about how evil the instanceof
comparison is, however I find it useful.
Upvotes: 2
Views: 2596
Reputation: 53
Reverend Gonzo's proposed solution violates encapsolation and doesn't answer the question. Encapsulation is violated, as ALL Monsters must now know if they like Elves or not, coupling all Monsters to a specific sub-type (Elves) in a very indirect and deep-seated way. It doesn't answer the question, because it's entirely possible for Orcs to like Elves, but Elves to not like Orcs!
I feel your initial solution using instanceof is entirely fine. While SLaks brings up a good point, I would argue that racist Elves (Elves not liking Orcs, and ALL Orc relatives sound pretty racist ;) ) are an entirely legitimate design decision, and not an indication of programmer error.
To take a step back and address "How do I have Elves that like some Orcs?", I think the best answer would be "Model WHY they like and dislike Monsters in general, and Orcs in specific". As long as you're keying off a single data point (type), you're always going to have limited behavior.
Upvotes: 2
Reputation: 40851
Neither. What you really should be doing is something like:
class Monster {
public abstract boolean likesElves();
}
class Orc extends Monster {
public boolean likesElves() {
return false;
}
}
class Elf extends Monster {
public boolean likesElves() {
return true;
}
}
Upvotes: 7