从HashMap存储和调用方法

时间:2017-11-14 13:35:02

标签: java design-patterns refactoring

我有2个文件:ImplementationProvider和CaseHandler。

ImplementationProvider:

class ImplementationProvider {
    public void method1(Object[] params) {}
    public void method2(Object[] params) {}
    ...
    public void method100(Object[] params) {}
}

CaseHandler:

class CaseHandler {
    ImplementationProvider ip; // auto injected
    public void handle(String s, String param) {
        switch(s) {
            case USE_CASE_ONE: ip.method1(param); break;
            case USE_CASE_TWO: ip.method2(param); break;
            ...
        }
    }   
}

如何重构CaseHandler,以便USE_CASE字符串是HashMap中的键,其中值是方法?我遇到的主要问题是参数的传播。这里的其他答案建议使用接口,但我需要在运行时提供参数。

2 个答案:

答案 0 :(得分:1)

如果您使用的是Java 8,则可以使用Consumer功能界面来参数化地图的值。

示例:

private static Map<String, Consumer<String>> MAP = new HashMap<>();
static {
    MAP.put("USE_CASE_ONE", (s) -> {/*TODO something with param s*/});
    // etc.
}

......然后在其他地方:

public void handle(String key, String param) {
        // TODO check key exists
        MAP.get(key).accept(param);
}

这里发生的是,对于每个给定的键集条目,您使用消耗String(您的param)的函数映射它。

然后,您在一行中调用给定参数上的Consumer accept

答案 1 :(得分:0)

这是我能想到的一种方式,使用Consumer功能界面:

Map<String,Consumer<Object[]>> methods = new HashMap<>();

methods.put (USE_CASE_ONE, param -> ip.method1(param));
methods.put (USE_CASE_TWO, param -> ip.method2(param));
...

public void handle(String s, String param) {
    methods.get(s).accept(new Object[]{param});
}

编辑:

如果您的方法需要两个参数,则可以使用BiConsumer界面:

Map<String,BiConsumer<String,List<String>>> methods = new HashMap<>();

methods.put (USE_CASE_ONE, (s,l) -> ip.method1(s,l));
methods.put (USE_CASE_TWO, (s,l) -> ip.method2(s,l));
...

public void handle(String s, String param) {
    methods.get(s).accept(someString,someListOfStrings);
}