Я немного не согласен с более опытным разработчиком по этому вопросу, и мне интересно, что другие думают об этом; наша среда - Java, EJB 3, сервисы и т. д.
Код, который я написал, вызывает службу для получения и создания вещей. Проблема, с которой я столкнулся, заключалась в том, что я получил исключения с нулевым указателем, которые не имели смысла. Например, когда я прошу службу создать объект, я получаю нулевое значение; когда я пытаюсь найти объект с известным действительным идентификатором, я получаю нулевое значение. Я потратил некоторое время, пытаясь выяснить, что не так в моем коде; поскольку я менее опытен, я обычно предполагаю, что сделал что-то не так, но оказывается, что причиной нулевого возврата была безопасность. Если у пользователя, использующего мой сервис, не было необходимых прав для целевой службы, он просто возвращает ноль. Большинство других сервисов здесь не очень хорошо документированы, поэтому, очевидно, это то, что вы должны знать.
Это довольно запутанно, поскольку разработчик пишет код, который взаимодействует со службой. Для меня было бы гораздо больше смысла, если бы сервис предоставил исключение, которое сообщило бы мне, что у пользователя нет необходимых разрешений для загрузки этой вещи или ее создания; Тогда я бы сразу узнал, почему мой сервис не работает должным образом.
Более опытный разработчик, написавший сервис, утверждал, что запрос данных не является условием ошибки и что исключения должны создаваться только в состоянии ошибки, а не тогда, когда пользователь не имеет доступа к данным. Эти данные часто ищутся в графическом интерфейсе, и для тех пользователей, у которых нет необходимых разрешений, эти вещи просто «не существуют». Итак, вкратце: спрашивать не неправильно, следовательно, не исключение. Методы get возвращают ноль, потому что этим пользователям эти вещи «не существуют». Методы создания возвращают ноль, когда пользователю не разрешено создавать эту вещь.
Это нормальная и / или хорошая практика? Я предпочитаю использовать исключения, потому что мне гораздо легче узнать, что происходит. Так что я бы, например, также предпочел бы генерировать исключение NotFoundException, если вы запрашивали объект с недопустимым идентификатором, а не возвращали ноль.
источник
Ответы:
Запрашиваемая вещь не может быть ошибкой, но отсутствие прав на то, что вы просили, безусловно, является ошибкой. Исключения - это альтернативный способ сообщения об исключительных условиях, который следует использовать вместо специальных возвращаемых значений (например
null
, который, как вы написали, абсолютно бесполезен, если есть> 1 возможных причин, по которым все может пойти не так (даже если ровно 1 возможная причина, в следующей версии может быть 2 возможные причины, поэтому использованиеnull
в качестве возвращаемого значения, указывающего на сбой, приведет к рисованию себя в угол)). Если служба не сообщает каким-либо образом, почему она не будет выполнять то, о чем вы просили, то это определенно плохой дизайн.Использовать ли специальное возвращаемое значение (например, отрицательные целые числа полезны для функций, которые обычно возвращают неотрицательное целое число), исключение, глобальный обработчик ошибок или регистратор и т. Д., В конце подробно рассматривается реализация. Выбор зависит от языка, ситуации, условностей, а также от вкуса. Суть в том, что должен быть какой-то прямой способ выяснить, почему что-то не работает. В противном случае ваш единственный вариант - использовать разные варианты, чтобы выяснить, что соотносится с поведением черного ящика, и это пустая трата времени.
String.substring()
бросает,IndexOutOfBoundsException
если индекс выходит за пределы. Я не могу думать о каких-либо преимуществах возвратаnull
вместо этого, хотя - с философской точки зрения - можно утверждать, что aString
не содержит ничего вне своих границ, поэтому тогдаnull
будет логичным возвращаемым значением. Быть логико-философским и практичным, очевидно, два разных животного.источник
substring
возврата пустой ссылки. ИМХО, должно быть две отдельные функции - одна из которых обещает либо вернуть запрошенное количество символов, либо выдать исключение, а одна из которых возвращает столько, сколько может. Каждый метод был бы значительно лучше другого в некоторых контекстах.Это сводится к тому, что контракт. Если в вашем контракте говорится, что вы можете запросить что-то, что не существует, в нем должно быть указано, что происходит (ноль или нулевой объект).
С другой стороны, если в вашем контракте говорится, что вы должны сначала вызвать другой метод (
DoesSomethingExist()
), а затем вызватьGet
метод, то в вашем контракте может быть сказано, что вы можете получить только те вещи, которые существуют, и выдать исключение, если они этого не делают. Сообщение об исключении может содержать что-то вроде «ОбязательноDoesSomethingExist()
сначала позвоните », что является полезным сообщением об ошибке.источник
findAllThings
метод, я бы сказал, что целесообразно возвращать пустой список или подмножество, если есть некоторые или все вещи, которые вам не разрешено видеть. Точно так же я мог бы в блоге только перечислять сообщения для редактирования, принадлежащие текущему пользователю. Но если этот пользователь попытался изменить URL-адрес и отредактировать другой пост ...Единого универсального ответа на этот вопрос не существует. Использовать ли исключения или возвращать ноль, зависит от ситуации.
Вместо того, чтобы смотреть на это чисто с догматической точки зрения, посмотрите на интерфейс как на пользовательский интерфейс . Пользовательские интерфейсы должны быть пригодными для использования . Поэтому, независимо от вашего собственного мнения о «правильном» способе сделать что-то, выберите метод, который наиболее удобен с точки зрения того, кто использует ваш интерфейс.
Если вызывающая сторона должна знать, почему объект не возвращается, необходимо сделать исключение. Если, однако, общая концепция - «если у вас нет разрешения, он не существует», то ноль является приемлемым.
В частности, в вашем случае я бы сказал, что нулевые значения вполне приемлемы для поиска элемента, если вызывающий абонент сначала должен войти в систему или подключиться к серверу. Тогда вам скажут, что у вас есть разрешение или нет. Когда вы проходите мимо ворот, разумно, что когда вы ищете что-то, что у вас нет разрешения на просмотр (или даже знаете, что оно существует), вы должны получить ноль.
Если, с другой стороны, у вас нет начального соединения или шага входа в систему, исключение имеет смысл. Если вызывающая сторона знает, что элемент существует, и не получает его обратно, API не помогает просто возвратить ноль.
Однако для создания предмета это другая история. Предположительно, для этого может быть много причин - нет разрешений, неверные параметры, недостаточно памяти на сервере и т. Д. Если разработчик получает нулевое значение для всех этих условий, он не может определить правильный порядок действий. ,
Итак, чтобы ответить на вопрос, спросите себя, какое наиболее подходящее решение с точки зрения того, кто использует сервис. Может случиться так, что то, как вы его используете, нетипично, и для наиболее распространенного случая ноль - это правильный ответ.
Так что не вступайте в религиозную войну из-за этого, решите, что подходит именно для этой конкретной проблемы.
источник
Я определенно думаю, что это плохой дизайн . Нулевой указатель не является правильным ответом для меня, и им может быть сложно управлять.
Если пользователь пытается подключить службу без надлежащих учетных данных, я должен ответить с четким и кратким ответом. Ответ может быть исключением или специальным объектом, но не нулевым.
Вы должны оставить нулевой ответ, если сетевое соединение разорвано или произошла другая непредвиденная критическая неисправность.
Кроме того, время, которое вы тратите на понимание, почему вы получили ноль, является сильным аргументом. Любой фрагмент кода должен быть прост для понимания и использования. Имея нулевое значение, это не так.
источник
Принимая во внимание хороший дизайн программного обеспечения, вы должны думать о жизни вашего проекта.
Возвращаясь
null
, как уже было сказано, вы не предоставляете никакой информации клиенту. Посмотрите, что случилось с вами, сначала вы не поняли, в чем проблема. Более того, если нет документации, это беспорядок.Выбрасывая исключение, вы можете сказать, что пошло не так. Вы можете даже настроить отображаемый текст, чтобы быть более конкретным, если хотите.
С другой стороны, вернувшись,
null
вы заставляете клиента выяснить, что происходит.Кроме того, вы поняли, что есть проблема, потому что вы получили в другом месте а
NullPointerException
. Теперь представьте, что вы не сохраняете возврат этой функции ... Вы будете вынуждены окружать каждый вызов этой функцииif else
блоком ...С моей точки зрения, возвращение
null
- плохая практика.источник
С моей точки зрения, это не имеет смысла.
Запрос данных без разрешения должен привести к исключению, потому что это неожиданный результат - без результата - без надлежащего доступа.
Аналогия : код ответа для
GET
без авторизации не200 ok
с данными, это на самом деле401 Unauthorized
.источник
Возвращать ноль не очень хорошо. Это ничего вам не говорит. Возьмем, к примеру, если приложение пытается что-то найти, а для обеих проблем безопасности ответ нулевой, а если элемент не существует, то как вы скажете разницу между ними?
Значимый ответ может позволить приложению сделать логический выбор относительно того, что делать дальше или как решать проблемы.
источник
Если основной причиной является не прошедший проверку подлинности пользователь, то я предпочитаю жесткий ответ HTTP 401, возможно, с перенаправлением на симпатичную страницу сообщения (и уведомлением того, кто заботится). Причины, связанные с авторизацией, чаще встречаются в каждом конкретном случае; есть аргументы для возврата ошибок HTTP (скажем, 403) и аргументы для возврата специальных правильно сформированных кодов / сообщений в ответе службы.
Исключения следует использовать только в исключительных обстоятельствах и означать, что что-то пошло не так. Я не согласен, что они должны быть перегружены, чтобы означать «не разрешено». (То же самое верно для нулевого возвращаемого значения: я не согласен, что оно должно использоваться, чтобы означать «не разрешено».)
источник
Чтобы играть в адвоката дьяволов, я попытаюсь принять сторону возврата нуля.
По моему мнению, есть только одна ситуация, когда такой ответ является почти приемлемым, и это, как и в этом случае, когда речь идет о безопасности.
Очень легко случайно раскрыть детали вашей системы, о которых посторонние люди не должны знать. Этого следует избегать.
Взять, к примеру, проверку имени пользователя и пароля. Возврат ошибок «Имя пользователя не найдено» и «Неверный пароль» в виде отдельных кодов ошибок, очевидно, откроет вам серьезные проблемы с безопасностью, поскольку кто-то может сначала найти действительное имя пользователя, а затем найти пароль. Возврат универсального «Неверное имя пользователя / пароль» будет лучшим вариантом.
Таким образом, в данном конкретном случае я бы сказал, что возвращение почти нормально,
null
но я согласен, с ним было бы очень неприятно работать.источник
null
- это наименее полезный ответ. Почти все остальное потенциально может быть использовано для обнаружения чего-либо в системе. Причина, по которой ОП жаловалась, заключалась в том, чтоnull
возвращение не только не объясняло ничего, но и было бесполезным. Это преднамеренная цель ... ничего не сказать и быть бесполезным. Миссия выполнена на мой взгляд.Я думаю, что возвращать ноль недружественно, когда клиент вызывает этот метод и возвращает ноль, клиент не знает, что произошло и почему он возвратил ноль. Таким образом, мы должны дать исключение, которое имеет смысл, и предоставить документацию для описания этого исполнения.
источник