Как работать с огромным количеством параметров запроса if / else (например, filter) - PullRequest
4 голосов
/ 11 февраля 2020
Веб-служба

A Java предназначена для разработки, которая должна иметь дело как минимум с 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
 }

....

Мой вопрос: как справиться с такими ситуациями? т.е. есть ли какие-либо ярлыки / шаблоны, чтобы минимизировать рабочую нагрузку здесь?

1 Ответ

2 голосов
/ 11 февраля 2020

Общая идея состоит в том, чтобы построить функцию отображения: входные перестановки => обработчик результатов.

Для этого используйте логические условия 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.

Далее ... предположим, что построена карта, в которой значением одной записи является объект, представляющий «обработчик результатов» для любого ключа. Допустим, этот объект реализует OutcomeProcessor.

HashMap<Integer,OutcomeProcessor> ourMap;

Каждое значение обработчика результатов имеет значение ключа, которое является маской. Так, например, значение ключа 0x14 будет означать, что для вызова процессора должны присутствовать параметры 'c' (the 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>);
   }
}

Довольно просто на самом деле. :)

Несколько свойств этого подхода:

  • один экземпляр входной перестановки (например, наличие & f & h) может (при желании) дать несколько результатов.
  • один результат может быть вызван из нескольких входных перестановок (например, обработчик результатов может потребоваться b & c (0x6) и входы (a, b, c, d) или (b, c, f) - оба случая ввода могут вызывать этот процессор.)
  • Вы могли бы стать более сложным и иметь результат Процессор возвращает результат, который очищает обслуживаемые им биты. И продолжайте цикл до тех пор, пока все параметры не будут обслужены.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...