在Java中,如何基于参数值进行分派?

在Java中,如何基于参数值进行分派?,java,python,dispatch,Java,Python,Dispatch,例如,当我有一个enum或一个String并且我想根据该参数的值进行分派时,会出现一个重复模式: public void myMethod(字符串参数){ if(参数等于(某物)){ doSomething(); }else if(参数等于(somethingElse)){ doSomethingElse(); } } 摆脱冗长的if或case语句的惯用方法是什么?我在考虑python中的单一分派通用函数,但我想基于值而不是类型分派 @fun.register(int) 定义(arg,verb

例如,当我有一个
enum
或一个
String
并且我想根据该参数的值进行分派时,会出现一个重复模式:

public void myMethod(字符串参数){
if(参数等于(某物)){
doSomething();
}else if(参数等于(somethingElse)){
doSomethingElse();
}
}
摆脱冗长的
if
case
语句的惯用方法是什么?我在考虑python中的单一分派通用函数,但我想基于值而不是类型分派

@fun.register(int)
定义(arg,verbose=False):
如果冗长:
打印(“数字强度,呃?”,end=“”)
打印(arg)
@乐趣。注册(列表)
定义(arg,verbose=False):
如果冗长:
打印(“枚举此:”)
对于i,枚举中的元素(arg):
打印(i,elem)

您可以在java中使用方法重写。。所以等价物应该是

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
}
public void doSomething(字符串arg){
//当param为string时执行某些操作
}
公共无效剂量测定(列表参数){
//当param是字符串列表时,执行其他操作
}

我发现这在处理具有多个“操作”的表单(例如)时最为常见。虽然这看起来有些过分,但很多时候,简单地“注册”动作处理程序实际上更干净(在许多方面,更容易)

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();

}
公共类调度程序{
私有映射actionHandlerMap=newHashMap();
公共void执行(字符串操作){
ActionHandler=actionHandlerMap.get(操作);
if(null==处理程序){
//没有处理程序-是否引发异常?
}
handler.execute();
}
public void addActionHandler(ActionHandler处理程序){
actionHandlerMap.put(handler.getAction(),handler);
}
}
公共接口ActionHandler{
公共字符串getAction();
公共无效执行();
}

它绝对是更多的代码,但它是可扩展的、干净的,并且允许更好地分离关注点。它也更容易测试,这总是一件好事。

在Java enum中也是一个类,因此您可以扩展它并将其用作:

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();

请注意,单一分派通用函数与Java示例完全不同:它们根据类型分派(而Java代码根据值分派),并且它们考虑了继承和接口(ABC)实现(最简单的类型分派Java代码将使用
isinstance
)。感谢您指出。这将打开参数的类型,而不是值。不清楚OP想要哪一个,但我认为是后者。Python特性执行后期绑定,而不是重载的早期绑定。例如,Python中等价的
void delegate(Object a){doSomething(a);}
做了正确的事情,而Java要么调用
对象
重载,而不管
a的运行时类型是什么
,要么因为没有这种重载而失败。@DuncanJones除非OP严重误解了
singledispatch
,这是关于类型的。这就是PEP 443发布的所有内容。根据他的python代码片段,类型似乎是他所需要的,但同样,他的java代码片段告诉我们,情况并非如此。我重新表述了我的问题。我知道关于重载,我希望做的是基于值进行调度。