wgtifw
Last Updated: June 21, 2016
·
6.352K
· jxcoder

Java Tip #3. How to implement dynamic "switch".

In the Java language exists "switch" keyword and everyone (every Java related developer) knows how it works. However, what if some cases is not known on compile step? What if we want dynamically add cases? Answer is easy - implement own "switch" mechanism.

We need to some interface which mean case command.

interface Command {
    void execute();
}

We need to class which implements the Command interface and on execute method calling will do nothing (pattern Special case).

class DoNothingCommand implements Command {
    @Override public void execute() {}
}

Now, we ready to implement the Switcher class.

class Switcher {

    private Map<Integer, Command> caseCommands;

    private Command defaultCommand;

    private Command getCaseCommandByCaseId(Integer caseId) {
        if (caseCommands.containsKey(caseId)) {
            return caseCommands.get(caseId);
        } else {
            return defaultCommand;
        }
    }

    public Switcher() {
        caseCommands = new HashMap<Integer, Command>();

        setDefaultCaseCommand(new DoNothingCommand());
    }

    public void addCaseCommand(Integer caseId, Command caseCommand) {
        caseCommands.put(caseId, caseCommand);
    }

    public void setDefaultCaseCommand(Command defaultCommand) {
        if (defaultCommand != null) {
            this.defaultCommand = defaultCommand;
        }
    }

    public void on(Integer caseId) {
        Command command = getCaseCommandByCaseId(caseId);

        command.execute();
    }
}

Now, we ready to write Main class.

public class Main {
    public static void main(String[] args) {
        Switcher switcher = new Switcher();
        switcher.addCaseCommand(1, new Command() {
            @Override
            public void execute() {
                System.out.println("Command on {id: 1}");
            }
        });
        switcher.addCaseCommand(2, new Command() {
            @Override
            public void execute() {
                System.out.println("Command on {id: 2}");
            }
        });
        switcher.addCaseCommand(3, new Command() {
            @Override
            public void execute() {
                System.out.println("Command on {id: 3}");
            }
        });
        switcher.setDefaultCaseCommand(new Command() {
            @Override
            public void execute() {
                System.out.println("Command on {default}");
            }
        });

        for (int i = 1; i <= 4; i++) {
            switcher.on(i);
        }
    }
}

// output
Command on {id: 1}
Command on {id: 2}
Command on {id: 3}
Command on {default}

4 Responses
Add your response

9477

You can use Runnable interface instead Command. Save you one file.

over 1 year ago ·
9480

Hello, drabiter!

I don't think that it is a good advice. I think that using Runnable interface is not expected in this case.

over 1 year ago ·
9558

@jxcoder: but certainly the interface description for Callable fits this use case (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Callable.html)

over 1 year ago ·
27796

Thanks, Its an elegant solution for dynamic switch case.

over 1 year ago ·