Eric Yu
Eric Yu

Reputation: 27

Java: get rid of if else by using generic type

in my code, I've used many if-else statements. I've learned that if-else and switch statements are not an elegant way to code, is there a good way to refactor the following code?

Wall, Trap, Door and Floor are subclass of Tile

    public class Player{
    ...
        public void move(DIR dir) throws Exception {
            Position nextPos = checkMove(dir);
            Tile nextTile = TileManager.getTileType(nextPos.getSeq());
            if (nextTile instanceof Floor) {
                walk();
            } else if (nextTile instanceof Wall) {
                block();
            } else if (nextTile instanceof Trap) {
                trap();
            } else if (nextTile instanceof Door) {
                unlock();
            }
        }
        public void walk(){
            ...
        }
        public void block(){
            ...
        }
        public void trap(){
            ...
        }
    ...
    }

I've tried to solve this by using method overload

public void move1(DIR dir) throws Exception {
    Position nextPos = checkMove(dir);
    System.out.println(nextPos);
    Tile nextTile = TileManager.getTileType(nextPos.getSeq());
    moveTo(nextTile);
} 
public void moveTo(Floor next) throws Exception {
    walk();
}
public void moveTo(Wall next) throws Exception {
    block();
}
...

and there is a compilation error

The method move1(Floor) in the type Player is not applicable for the arguments (Tile)

I've read some post that suggest generic type might be a solution, but i dont know how to implement it.

Upvotes: 1

Views: 109

Answers (2)

Antonio
Antonio

Reputation: 774

Well, the style depends on the language. You may mix Java and Kotlin in a single project: https://kotlinlang.org/docs/tutorials/mixing-java-kotlin-intellij.html

You may create a Kotlin file in your existing Java project with something like this (not tested):

when (nextTile) {
   is Floor -> walk()
   is Wall -> block()
   is Trap -> Trap()
   is Door -> unlock()
   else -> throw IllegalArgumentException("Unknown expression")
}

Have a look at

https://try.kotlinlang.org/#/Kotlin%20Koans/Introduction/Smart%20casts/Task.kt

https://kotlinlang.org/docs/reference/typecasts.html

Upvotes: 1

Code-Apprentice
Code-Apprentice

Reputation: 83587

I've learned that if-else and switch statements are not an elegant way to code, is there a good way to refactor the following code?

One potential solution is to add an abstract method to Tile, let's call it action(). (Feel free to come up with a better name.) Then you can do nextTile.action() without the if statement. Then rename Floor.walk() to Floor.action() and similarly with the other specialized methods for each Tile subclass. This has the added benefit that you can create new Tile subclasses and move() will be able to handle them without any changes.

Upvotes: 6

Related Questions