Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

trouble making polymorphism defeat those switch/case statements

Continuing on previous questions (here, and here), I implemented a basic command pattern, created my command classes and coded to an interface, so when any command is used, to call the execute() method.

However, I am still finding myself unable to shake those case statements: I am reading each character from a master/decision String, which is made up of random, repeating characters A, B, C or D, and then I retrieve the related implementation of the command from a map and call its execute method.

My design was like this:

public interface Command {
    void execute();
}

public class CommandA implements Command{
  //implements execute() method
}

private Map myMap= new HashMap();
myMap.put("A", new CommandA);
myMap.put("B", new CommandB);
myMap.put("C", new CommandC);
myMap.put("D", new CommandD);

But, then when I read each instruction, again I have to resort to case statements:

switch(instructionFromString){
case 'A':{myMap.get("A").execute(); break;}
case 'B':{myMap.get("B").execute(); break;}
case 'C':{myMap.get("C").execute(); break;}
case 'D':{myMap.get("D").execute(); break;}

Obviously, somewhere along the way I managed to defeat the advantage of polymorphism against the case statements.

Could it be the kind of data structure I selected to store my commands? It can very well be a permanent data structure to just pull those commands from.

Another thing that comes to mind is the key/value naming that I used in my map. The way I tried to conceptually link each stored command to its associated instruction? i.e. Implementation of command "A", is stored on the map with key 'A' so it can match to the corresponding instruction "A"? That seems to me a bit unlikely though.

Any hint or further advice about my next move to remove those case statements once and for all would be highly appreciated. Many thanks in advance

like image 872
denchr Avatar asked Sep 06 '09 20:09

denchr


1 Answers

I may be missing something here, but instead of the switch statement, what's wrong with

((Command)myMap.get(instructionFromString)).execute();

If instructionFromString is a char, the convert it into a String before doing the map lookup, else use Character keys in your map.

Also, if you use a Java 5 generic map, then you can remove the cast to Command. A cleaned up version would be:

private Map<Character, Command> myMap = new HashMap<Character, Command>();
myMap.put('A', new CommandA());
myMap.put('B', new CommandB());
myMap.put('C', new CommandC());
myMap.put('D', new CommandD());

followed by:

char instructionFromString = ....
myMap.get(instructionFromString).execute();
like image 152
skaffman Avatar answered Nov 09 '22 23:11

skaffman