2009-07-30 2 views
2

Когда я впервые перешел из c в Java, я подумал, что я закончил все досадные проверки параметров в начале каждой функции. (Blessed исключения)Проверка всех функциональных параметров во всех функциях

В последнее время я понял, что я медленно вернуться к этой практике еще раз, и я начинаю действительно раздражен со всеми

if (null == a || null == b || null == a.getValue() || ...) 
{ 
    return null; 
} 

К примеру, у меня есть полезный класс, который анализирует веб-страницы и извлекает из них определенные элементы. Любой вызов функции DOM объекта с нулевыми элементами, как правило, приводит к исключению - Так что практически любой функции я пишу в этом классе есть бесчисленное количество нулевых проверок:

private URL extractUrl(Element element) throws Exception { 
if (null == element) { 
    return null; 
} ... 

public List<Object> getConcreteElements(String xpath) throws Exception { 
if (null == xpath) { 
    return Collections.emptyList(); 
}... 

public String getElementsAsXML(String xpath) throws Exception { 
if (null == xpath) { 
return null; 
}... 

в начале каждой функции. Это то, что я тоже должен использовать, или есть какая-то практика кодирования, о которой я не знаю, что может упростить мою жизнь?

+0

Более полный пример был бы удобным, трудно дать вам обобщение совета из того, что вы опубликовали. – skaffman

+0

Слишком мало информации. Нам нужен больше контекста, например, что такое подпись функции, какой язык (ы) вы используете и ПОЧЕМУ вы думаете, что вам нужно это делать. –

+0

Спасибо за комментарии, я надеюсь, что теперь станет яснее – Yossale

ответ

2

Да, они абсолютно раздражают. Несколько мелких вещей, которые я обнаружил, по крайней мере, сводят к минимуму следующее:

  • Четко документируйте внутренние функции api, которые не могут вернуть нуль или при каких условиях вы можете ожидать нуль. Если вы можете доверять своей документации, по крайней мере, это позволяет избежать нулевых проверок в определенных местах.
  • Некоторые идиомы минимизируют нулевые проверки - например.

    если (строка = NULL & & String.equals ("А") -> если ("A" .equals (строка))

  • затмение (как FindBugs, я думаю, и, вероятно, многие другие ide) могут быть установлены для отметки избыточных нулевых проверок или отсутствия нулевых проверок. Не идеально, но это помогает.

Но в целом вы правы.Если бы у моего кода не было нулевых проверок и протоколирования, там вообще не было бы;)

4

На публичной границе вашего компонента вам всегда нужно будет выполнить проверку данных.

Для внутренних методов, assert Если правильные значения верны, то лучше.

Возвращение null - это то, что лучше избегать, если можно. Либо это не так, а там, чтобы указать, что есть ошибка перед вами (внутренний случай) или вернуть пустой или по умолчанию объект, если есть такая вещь (общедоступный случай).

1

Только check-null-return-null, если это имеет смысл для вашего приложения. Возможно, что возврат null просто вызывает проблемы для клиентского кода, который не ожидает возврата обратно. Может быть, нет разумного значения возврата в ответ на плохой ввод, и в этом случае используйте исключения.

Что касается того, следует ли проверять аргументы, это зависит от того, кто использует эту функцию. если это частная функция, это может быть слишком сложно проверить. Если это общедоступная функция API, вы абсолютно должны ее проверить.

7

Возврат null означает, что вызывающий должен ВСЕГДА проверять результат по вашему методу. Значение БОЛЬШИХ несчастных нулевых проверок.

Рассмотрим вместо этого шаблон NullObject, где вы возвращаете действительный объект, но с пустыми операциями. То есть пустой список, если коллекция возвращается или аналогична.

+0

+1 за советом, а не с возвратом нулевых значений –

1

По моему опыту, приложения Java легче поддерживать, если по умолчанию «контракт» для любого API равен null значения параметров и null результаты не допускаются. Если метод предназначен для разрешения аргумента null или возвращает null, значение и обстоятельства должны быть четко указаны в Javadoc.

Если передано null, где API не позволяет это конкретно, это ошибка, и лучше всего быстро работать с NPE. (IMO, нет необходимости документировать возможность NPE ... это можно предположить.) Если null не является значимым (документированным) значением аргумента, практика тестирования для null и возврата null служит только для распространения плохих данных и затруднить отладку вашего кода. Если ваш метод использует аргумент null, который вызывает NPE, пусть будет так. Если аргумент не используется, но он сохраняет значение для использования в будущем, то стоит проверить значение null и явно выбросить NPE.

Я также стараюсь избегать (обычно ложных) оптимизаций использования null для представления пустых списков или пустых массивов, по крайней мере, на уровне API.

В настоящее время существуют ситуации, когда для дизайна API имеет смысл использовать null s; например в API, где параметр объекта реализует какое-то поведение/политику плагина, или null используется, когда дополнительный параметр метода не предоставляется. Но вам нужно подумать об этом и задокументировать его.

+0

Но не являются ли ядерные энергетические Enemas чуть-чуть переборщиком? –

1

Если вы проверяете незаконные значения, не стесняйтесь бросать IllegalArgumentExceptions, чтобы уведомить вызывающего, что он сделал ошибку. Вы можете скрыть краевое/нелегальные проверки в частных методах значения, что повышает читаемость кода, как - просто принимать один из ваших примеров:

private URL extractUrl(Element element) throws Exception { 

    validateExactUrlParameter(element); 

    // the real url extraction code 

} 

private static validateExactUrlParameter(Element element) 
           throws IllegalArgumentException { 

    if (null == element) { 
    throw new IllegalArgumentException("Null value not allowed for exactUrl method"); 
    } 

    // do some more checks here, if required 

} 

Если вы хотите, чтобы избежать попробовать/поймать блоки, а затем рассмотреть метания исключаемые исключения (RuntimeException или пользовательские подклассы).

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