如何处理大量查询参数的 if/else 语句(例如过滤器)

How to deal with a huge number of query params' if/else statement (e.g. filter)

A​​ Java 的 Web 服务旨在开发至少应处理 10 @QueryParam。也就是说,假设我有 10 个查询参数 ,我最终会得到 90 个 if-else 语句(我认为,最少)试图构建所有可能的编译。

例如:

public Response getMethod(
        @QueryParam("a") List<String> a,
        @QueryParam("b") List<String> b,
        @QueryParam("c") List<String> c,
        @QueryParam("d") List<String> d,
        @QueryParam("e") List<String> e

       // ... etc
){

 if (a != null && b == null && c == null ...)
 {
    // bla bla bla - 1
 } 

 else if (a != null && b != null && c == null ...) 
 {
    // bla bla bla - 2
 }

....

我的问题是如何处理这种情况?即是否有任何快捷方式/模式可以最大限度地减少这里的工作量?

一般的想法是构建一个映射函数:输入排列 => 结果处理器。

为此,使用 10 多个布尔条件(a != null,b != null ...)作为位字段来构建 10 位密钥。

// assume a,b,c,d...j are in scope and null or not-null
int inK = ((((a != null) ? 1 : 0) << 0 |
            ((b != null) ? 1 : 0) << 1 |
             ...
            ((j != null) ? 1 : 0) << 9))

// so now inK is a 10-bit number where each bit represents whether the
// corresponding parameter is present.

下一步...假设构建了一个映射,其中单个条目的值是表示任何键的 "outcome processor" 的对象。假设这个对象实现了 OutcomeProcessor。

HashMap<Integer,OutcomeProcessor> ourMap;

每个结果处理器值都有一个键值,它是一个掩码。例如一把钥匙 0x14 的值表示参数 'c'(4)和 'e'(0x10)必须 在场调用处理器。

OutcomeProcessor 需要访问它需要的任何参数,但 接口是通用的,因此将参数作为列表(在本例中为列表)或更一般的集合提供。

因此,要构建 ourMap,假设您知道映射和处理器实现:

// first outcome processor (an instance of `OutcomeProcessor1` needs 'a' and 'c' input parameters
ourMap.put(0x5, new OutcomeProcessor1());

// second outcome processor (needs 'a' and 'd')
ourMap.put(0x9, new OutcomeProcessor2());

// so you'll see that if the input is 'a','c' and 'd' then both processors
// are invoked.

// repeat for all possible outcome processors

接下来将蒙版应用于地图

for (Map.Entry<Integer, OutcomeProcessor> entry : ourMap.entrySet()) {
   int mask = entry.getKey();
   if ((mask & inK) == mask) {
      // invoke processor
      entry.getValue().method(<list of parameters>);
   }
}

真的很简单。:)

这种方法的一些特性:

  • 输入排列的单个实例(例如存在 a & f & h)可以(如果需要)产生多个结果。
  • 可以从多个输入排列调用单个结果(例如,结果处理器可能需要 b & c (0x6) 并且输入是 (a,b,c,d) 或 (b,c,f) - 两者输入案例可能会调用此处理器。)
  • 您可能会变得更复杂,并让 OutcomeProcessor return 得到一个清除其服务的位的结果。并继续循环,直到所有参数都得到服务。