Проверка всех параметров функции во всех функциях - PullRequest
2 голосов
/ 30 июля 2009

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

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

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;
}...

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

Ответы [ 6 ]

7 голосов
/ 30 июля 2009

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

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

4 голосов
/ 30 июля 2009

На общедоступной границе вашего компонента вам всегда придется проверять данные.

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

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

2 голосов
/ 30 июля 2009

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

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

    if (string! = Null && string.equals ("A") -> if ("A" .equals (string))

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

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

1 голос
/ 30 июля 2009

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

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

}

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

1 голос
/ 30 июля 2009

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

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

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

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

1 голос
/ 30 июля 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...