替换if else语句

时间:2016-07-12 09:13:45

标签: java algorithm design-patterns

我的代码看起来像这样:

if(num == 1) {
return new Alg1();
} else if (num == 2) {
return new Alg2();
}
...
else if (num == n) {
return new AlgN();
}

我曾尝试使用策略模式,但似乎它不能满足减少if语句的任务,请你建议我做其他方法,谢谢

3 个答案:

答案 0 :(得分:6)

您可以使用反射

try {
    return Class.forName("mypackage.Alg" + num).newInstance();
} catch (Exception e) { 
    // handle exception
}

您可以选择使用RuntimeException进行换行,或者如果它是您期望的那样,则可以将其换行

public static Algorythm loadAlgo(int n) throws IOException {
    try {
        return Class.forName("mypackage.Alg" + num).newInstance();

    } catch (Exception e) { 
        if (e instanceof IOException) 
            throw (IOException) e;
        throw new IOException("Unable to load Algo", e);
    }

您必须使用此newInstance()方法捕获所有异常,而不仅仅是已检查的异常,因为它不会包含构造函数中抛出的异常。你可以使用更长的

try {
    return Class.forName("mypackage.Alg" + num).getConstructor().newInstance();
} catch (Exception e) { 
    // handle exception
}

然而,在这种情况下它没有太大区别,除非抛出的异常将被包装,你可能需要打开它们才能看到它们。

答案 1 :(得分:6)

除非您要提供40亿个Alg*课程,否则请使用enum代替int

enum Strategy {
  ALG_1 { @Override public Alg1 newInstance() { return new Alg1(); },
  ALG_2 { @Override public Alg2 newInstance() { return new Alg2(); },
  // ...
  ;

  public abstract AlgBase newInstance();
}

然后不需要任何条件:

return strategy.newInstance();

其中strategyStrategy的实例。

答案 2 :(得分:3)

如果要动态添加新算法,可能需要查看spi。 https://docs.oracle.com/javase/tutorial/ext/basics/spi.html。这些方法意味着所有算法都必须是初始化的,如果一个算法失败,那么任何算法都是可用的。

使用文本文件,您可以注册接口的实现并通过以下方式解决这些实现:

    ServiceLoader<Algorithm> algorithms = ServiceLoader.load(Algorithm.class);
    for (Algorithm algorithm : algorithms) {
        if (algorithm.getId().equals(num)) {
            return algorithm;
        }
    }
    throw new IllegalArgumentException("Algorithm with num " + num + " does not exist");

这将为该算法的所有实现返回Iterable。你可以遍历它们以找到正确的。

如果您在一次运行应用程序时经常解析算法,则可能需要将算法存储/缓存在Map中。

如果您不想使用spi,也可以手动创建此地图。

private static final Map<Integer, Algorithm> ALGORITHMS;

static {
    Map<Integer, Algorithm> algs = new HashMap<>();
    algs.put(1, new Alg1());
    algs.put(2, new Alg2());
    algs.put(3, new Alg3());
    ALGORITHMS = Collections.unmodifiableMap(algs);
}