2016-08-03 2 views
3

Вот моя проблема. У меня есть функция, называемая маршрутом, который работает правильно! Однако я хотел бы факторизовать контрольный блок параметров.Избегайте «Если (параметр == null)» оператор

Позвольте мне объяснить. Когда пользователь вводит URL-адрес для доступа к функции, он может поместить некоторые необязательные параметры (всего 6). По крайней мере один из этих параметров необходим для продолжения. Моя структура настроена так, чтобы присваивать нулевое значение параметрам, которые не были проинформированы пользователем.

Чтобы проверить, какие параметры были проинформированы, и проверить их, у меня есть блок:

public Result edit(String param1, String param2, String param3, String param4, String param5, String param6) { 

    Map<String, Object> parameters = new HashMap<>(); 
    if (param1 != null) { 
     // Checking function depending on data type (URL, Boolean, ..), return a clean param or throw an InvalidParamException 
     // Variable param depends on type returned by checkParamType1 
     param = checkParamType1(param1); 
     parameters.put("param1", param); 
    } 
    if (param2 != null) { 
     param = checkParamType1(param2); 
     parameters.put("param2", param); 
    } 
    if (param3 != null) { 
     param = checkParamType2(param3); 
     parameters.put("param3", param); 
    } 
    if (param4 != null) { 
     param = checkParamType2(param4); 
     parameters.put("param4", param); 
    } 
    if (param5 != null) { 
     param = checkParamType3(param5); 
     parameters.put("param5", param); 
    } 
    if (param6 != null) { 
     param = checkParamType3(param6); 
     parameters.put("param6", param); 
    } 
    assert(parameters.size() > 0, "At least one parameter required"); 

    // [TREATMENT] 
} 

Мой вопрос, по вашему мнению, можно факторизовать этот блок?

работает мой проект на JAVA 8.

Спасибо :)

+2

Можете ли вы объяснить, что означает * factorize *? – alzee

+0

хороший ресурс http://winterbe.com/posts/2015/03/15/avoid-null-checks-in-java/ –

+0

Что делают методы checkParamType [123]? Разнообразны ли они для разных аргументов? – Matt

ответ

6

Лучшее, что вы можете сделать IMHO, - это извлечь метод и использовать ссылку на метод для вашей настраиваемой проверки. Что-то вроде этого:

private void checkAndAssign(Map<String, Object> map, String paramName, String paramValue, Function<String, Object> checker){ 
    if(paramValue!=null){ 
    Object param = checker.apply(paramValue); 
    map.put(paramName, param); 
    } 
} 

public Result edit(String param1, String param2, String param3, String param4, String param5, String param6) { 

    Map<String, Object> parameters = new HashMap<>(); 
    checkAndAssign(map, "param1", param1, MyClass::checkParam1); 
    checkAndAssign(map, "param2", param2, MyClass::checkParam2); 
    checkAndAssign(map, "param3", param3, MyClass::checkParam3); 
    checkAndAssign(map, "param4", param4, MyClass::checkParam4); 
    checkAndAssign(map, "param5", param5, MyClass::checkParam5); 
    checkAndAssign(map, "param6", param6, MyClass::checkParam6); 
    assert(parameters.size() > 0, "At least one parameter required"); 

    // [TREATMENT] 
} 

MyClass :: checkParam1 - это ссылка на метод. Компилятор позволит вам заменить такую ​​ссылку на функциональный интерфейс, например Function.

См. Method References в учебнике по Java 8.

+2

Я понимаю, что метод 'checkParamType' специфичен для каждого параметра. Таким образом, вы не можете использовать 'checkParamType1' для всех параметров – Dherik

+2

в порядке, я обращусь к этому в следующем обновлении –

+1

Теперь он поддерживает пользовательские функции проверки –

0

Сначала вы можете использовать операторы case switch. Но в ОО-языках, было бы лучше использовать шаблон проектирования, как цепь ответственности ...

+0

Не могли бы вы немного разобраться? Как бы вы использовали Chain Of Responsibility здесь? – Hulk

2

В Java-можно заменить

if (param1 != null) { 
    param = checkParamType1(param1); 
    parameters.put("param1", param); 
} 

С чем-то вроде:

Optional.ofNullable(param1) 
    .ifPresent((param) -> parameters.put("param1", checkParamType1(param))); 
+6

Абсолютно верно. Но вы действительно видите здесь выгоду? Это просто искусство ради искусства. Оригинальная проверка будет еще короче и более простой. если (param1! = Null) параметры.put ("param1", checkParamType1 (param1)); – Matt

+0

@Matt Это вопрос точки зрения, поэтому я разрешаю ПО решать, что он предпочитает больше всего. –

+1

Это очень небольшое улучшение. Столь маленький он не должен рассматриваться как ответ. – plalx

0

, если количество аргументов не ограничено, попробуйте использовать параметр var-args и цикл по результирующему массиву.

public Result edit(String... params) { 
    Map<String, Object> parameters = new HashMap<>(); 
    IntStream.range(0, params.length).forEach(idx -> { 
     String param = params[idx]; 
     if (param != null) { 
      Object p = checkParamType(param); 
      parameters.put("param" + idx, p); 
     } 
    }); 
} 
+2

. Вы не считали, что он имеет несколько методов checkParamType() – Matt

+1

Это интересное решение, но, как сказал @Matt, вы не считаете, что у меня несколько методов checkParamType :) Спасибо! – Twisky

Смежные вопросы