In my application I have a 2d array of entities to represent a grid. Each location in the grid can either be empty or occupied by an entity (in this case it's just a person or wall). Right now I use instanceof
to check whether an entity is a person or a wall.
I was thinking of giving each entity a method which returns an enum
stating their type so i.e. a wall entity would return EntityType.WALL
. I was wondering if this is the best idea to remove the use of instanceof
or is instanceof
suitable in this scenario?
Having a chain of "instanceof" operations is considered a "code smell". The standard answer is "use polymorphism".
Probably most of you have already heard that using “instanceof” is a code smell and it is considered as a bad practice. While there is nothing wrong in it and may be required at certain times, but the good design would avoid having to use this keyword.
You can avoid the need of using instanceof if Item defines an abstract method, forcing each subclass to implement its own. Probably rethink your structure. The pattern you are describing is really an anti-pattern. Yes, in general using `instanceof`` is a symptom of a bad/poor design.
The instanceof operator and isInstance() method both are used for checking the class of the object. But the main difference comes when we want to check the class of objects dynamically then isInstance() method will work. There is no way we can do this by instanceof operator.
Use Tell, Don't Ask: instead of asking the objects what they are and then reacting on that, tell the object what to do and then walls or people do decide how they do what they need to do.
For example:
Instead of having something like this:
public class Wall { // ... } public class Person { // ... } // later public class moveTo(Position pos) { Object whatIsThere = pos.whatIsThere(); if (whatIsThere instanceof Wall) { System.err.println("You cannot move into a wall"); } else if (whatIsThere instanceof Person) { System.err.println("You bump into " + person.getName()); } // many more else branches... }
do something like this:
public interface DungeonFeature { void moveInto(); } public class Wall implements DungeonFeature { @Override public void moveInto() { System.err.println("You bump into a wall"); } // ... } public class Person implements DungeonFeature { private String name; @Override public void moveInto() { System.err.println("You bump into " + name); } // ... } // and later public void moveTo(Position pos) { DungeonFeature df = currentPosition(); df.moveTo(pos); }
This has some advantages.
First, you don't need to adjust a giant if then else tree each time you add a new dungeon feature.
Second, the code in the dungeon features is self-contained, the logic is all in the said object. You can easily test it and move it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With