【问题标题】:How can I dispatch based on a value of a parameter in Java?如何根据 Java 中的参数值进行调度?
【发布时间】:2013-07-10 12:08:55
【问题描述】:

当我有 enumString 并且我想根据该参数的值进行调度时,会出现重复模式:

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

摆脱冗长的ifcase 语句的惯用方法是什么?我正在考虑类似 python 中的单调度泛型函数之类的东西,但我想基于值而不是类型进行调度。

@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)

【问题讨论】:

  • 请注意,单分派泛型函数与您的 Java 示例完全不同:它们在 type 上分派(而 Java 代码在值上分派),它们采用继承和将接口 (ABC) 实现考虑在内(最简单的类型分派 Java 代码将使用 isinstance)。
  • 感谢您指出这一点。

标签: java python dispatch


【解决方案1】:

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

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

}

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

【讨论】:

    【解决方案2】:

    您可以在 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
    }
    

    【讨论】:

    • 这将打开参数的类型,而不是值。目前尚不清楚 OP 想要哪个,但我认为是后者。
    • Python 特性进行后期绑定,而不是重载的早期绑定。例如,void delegate(Object a) { doSomething(a); } 的 Python 等效项是正确的,而 Java 要么调用 Object 重载,而不管 a 的运行时类型如何,要么因为没有此类重载而失败。
    • @DuncanJones 除非 OP 严重误解 singledispatch,否则它与类型有关。这就是 PEP 443 的所有调度。
    • 基于他的python代码sn-p,看起来类型是他需要的,但同样,他的java代码sn-p告诉他。
    • 我重新表述了我的问题。我知道重载我想做的是基于价值进行调度。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多