Question

There is a recurring pattern when I have for example an enum or a String and I want to dispatch based on the value of that parameter:

public void myMethod(String parameter) {
    if(parameter.equals(something)) {
        doSomething();
    } else if(parameter.equals(somethingElse)) {
        doSomethingElse();
    }
}

What is the idiomatic way to get rid of the lengthy if or case statements? I'm thinking about something like the single dispatch generic functions in python but I want to dispatch based on value not on type.

@fun.register(int)
def _(arg, verbose=False):
    if verbose:
        print("Strength in numbers, eh?", end=" ")
    print(arg)

@fun.register(list)
def _(arg, verbose=False):
    if verbose:
        print("Enumerate this:")
    for i, elem in enumerate(arg):
        print(i, elem)
Was it helpful?

Solution

I find that this is most common when dealing with forms (as an example) that have multiple "actions". Although this may seem overkill, a lot of times it's actually much cleaner (and in many ways, easier) to simply "register" action handlers.

public class Dispatcher {

    private Map<String, ActionHandler> actionHandlerMap = new HashMap<String, ActionHandler>();

    public void perform(String action) {
        ActionHandler handler = actionHandlerMap.get(action);

        if (null == handler) {
            // no handler - throw an exception?
        }

        handler.execute();
    }

    public void addActionHandler(ActionHandler handler) {
        actionHandlerMap.put(handler.getAction(), handler);
    }

}

public interface ActionHandler {

    public String getAction();
    public void execute();

}

It is absolutely more code, but it's extensible, clean, and allows for a better separation of concerns. It's also much more easily testable which is always a good thing.

OTHER TIPS

you could use method overriding in java.. so the equivalent should be something like

public void doSomething(String arg) {
//do something when param is string
}

public void doSomething(List<String> arg) {
//do something else when param is a List of String
}

In Java enum is a class as well, so you could extextend it and use it as :

interface Doable {
     void doSomething();
}
enum Stuff implements Doable {
     ONE() {
        public doSomething() { System.out.println("do one");};
     },
     TWO() {
        public doSomething() { System.out.println("do two");};
     }
}
Doable s = Stuff.valueOf("ONE");
s.doSomething();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top