Лучший способ вернуть флаг состояния и сообщение из метода в Java - PullRequest
26 голосов
/ 10 декабря 2008

У меня обманчиво простой сценарий, и я хочу простое решение, но не очевидно, что является «наиболее правильным» или «наиболее Java».

Допустим, у меня есть небольшой метод аутентификации (клиент-клиент) в каком-то классе. Аутентификация может быть неудачной по ряду причин, и я хочу вернуть простое логическое значение для потока управления, но также вернуть сообщение String для пользователя. Вот те возможности, о которых я могу подумать:

  • Вернуть логическое значение и передать StringBuilder для сбора сообщения. Это самый близкий к C-стилю способ сделать это.
  • Бросьте исключение вместо возврата false и включите сообщение. Мне это не нравится, так как неудача не является исключительной.
  • Создайте новый класс с именем AuthenticationStatus с логическим значением и строкой. Это кажется излишним для одного маленького метода.
  • Сохранить сообщение в переменной-члене. Это может привести к состоянию потенциальной расы, и мне не нравится, что оно подразумевает некое состояние, которого на самом деле нет.

Любые другие предложения?

Редактировать Эта опция отключена

  • Вернуть ноль для успеха - это небезопасно?

Редактировать Решение:

Я выбрал самое ОО-решение и создал небольшой класс AuthenticationResult. Я бы не стал делать это на любом другом языке, но мне нравится это на Java. Мне тоже понравилось предложение возврата String [], поскольку это похоже на нулевой возврат, но безопаснее. Одним из преимуществ класса Result является то, что вы можете получить сообщение об успехе с дополнительной информацией, если требуется.

Ответы [ 17 ]

0 голосов
/ 10 декабря 2008

Вместо создания специального объекта для возвращаемого типа я обычно просто возвращаю массив, в котором хранится вся возвращаемая информация. Преимущество состоит в том, что вы можете расширить этот массив новыми элементами, не создавая новых типов и беспорядка. Недостатком является то, что вы должны точно знать, какие элементы должны присутствовать при возврате массива из определенного метода, чтобы правильно его проанализировать. Обычно я согласен с определенной структурой, так как первый элемент всегда имеет логическое указание на успех, второй - это строка с описанием, остальное необязательно Пример:

public static void main(String[] args)
{
    Object[] result = methodReturningStatus();
    if(!(Boolean)result[0])
        System.out.println("Method return: "+ result[1]);
}

static Object[] methodReturningStatus()
{
    Object[] result = new Object[2];

    result[0] = false;
    result[1] = "Error happened";

    return result;
}
0 голосов
/ 10 декабря 2008

Это единственный метод, когда у вас есть такое требование? Если нет, просто сгенерируйте общий класс Response с флагом isSuccessful и строкой сообщения и используйте его везде.

Или вы можете просто заставить метод возвращать нуль, чтобы показать успех (не очень, и не позволяет возвращать успех И сообщение).

0 голосов
/ 10 декабря 2008

Я использую «крошечный класс» сам, обычно с внутренним классом. Мне не нравится использовать аргументы для сбора сообщений.

Кроме того, если метод, который может дать сбой, является «низкоуровневым» - например, поступающий с сервера приложений или уровня базы данных, я бы предпочел вернуть Enum со статусом возврата, а затем перевести его в строку в Уровень графического интерфейса. Не передавайте пользовательские строки на низком уровне, если вы когда-либо собираетесь интернационализировать свой код, потому что тогда ваш сервер приложений может отвечать только на одном языке за раз, вместо того, чтобы разные клиенты работали на разных языках.

0 голосов
/ 10 декабря 2008

Как насчет возврата строки. Пусто или Нуль для успеха. Сообщение об ошибке в случае сбоя. Самое простое, что будет работать. Однако не уверен, что он хорошо читается.

0 голосов
/ 10 декабря 2008

Успешная аутентификация должна быть "нормальным" случаем, поэтому ошибка аутентификации является исключительным случаем.

Каковы различные строки статуса для пользователя в любом случае. Я вижу только два, успех или неудачу. Любая дополнительная информация является потенциальной проблемой безопасности. Другое преимущество решения с исключениями состоит в том, что оно не может быть вызвано неверно, и случай сбоя более очевиден. Без исключений, вы пишете:

if (authenticate()) {
  // normal behaviour...
}
else {
  // error case...
}

Вы можете случайно вызвать метод, игнорируя возвращаемое значение. Код "нормального поведения" затем выполняется без успешной аутентификации:

authenticate();
// normal behaviour...

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

if (isAuthenticated()) {
//...
}
0 голосов
/ 10 декабря 2008

Здесь много хороших ответов, поэтому я буду кратким.

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

Если вы собираетесь вернуть несколько значений, потратьте 10 минут на создание универсального PairTuple (также может быть больше пары TripleTuple, я не буду повторять приведенный выше пример) и вернуть ваши значения таким образом. Я ненавижу иметь маленькие объекты стиля dto, чтобы возвращать различные множественные значения, они просто загромождают место.

0 голосов
/ 10 декабря 2008

Я бы выбрал вариант Исключение на первом месте.

Но, во-вторых, я бы предпочел технику в стиле C:

public boolean authenticate(Client client, final StringBuilder sb) {
    if (sb == null)
        throw new IllegalArgumentException();
    if (isOK()) {
        sb.append("info message");
        return true;
    } else {
        sb.append("error message");
        return false;
    }
}

Это не так странно, и это делается во многих местах в рамках.

...